/** * Generates some preamble (i.e. comments, language declaration section etc.) and adds it to * this.code. * * @param _root - the diagram root element * @param _indent - the current indentation string * @param varNames - list of variable names introduced inside the body */ @Override protected String generatePreamble(Root _root, String _indent, StringList varNames) { code.add(""); // Variable declaration proposals (now with all used variables listed) insertComment("TODO: Declare local variables here:", _indent); for (int v = 0; v < varNames.count(); v++) { insertComment(varNames.get(v), _indent); } code.add(""); return _indent; }
/** * Composes the heading for the program or function according to the C language specification. * * @param _root - The diagram root * @param _indent - the initial indentation string * @param _procName - the procedure name * @param paramNames - list of the argument names * @param paramTypes - list of corresponding type names (possibly null) * @param resultType - result type name (possibly null) * @return the default indentation string for the subsequent stuff */ @Override protected String generateHeader( Root _root, String _indent, String _procName, StringList _paramNames, StringList _paramTypes, String _resultType) { // START KGU#178 2016-07-20: Enh. #160 if (topLevel) { insertComment("Generated by Structorizer " + Element.E_VERSION, _indent); code.add(""); subroutineInsertionLine = code.count(); // default position for subroutines subroutineIndent = _indent; } else { code.add(""); } // END KGU#178 2016-07-20 if (_root.isProgram == true) { code.add(_indent + "using System;"); code.add(_indent + ""); // START KGU 2015-10-18 insertBlockComment(_root.getComment(), _indent, "/**", " * ", " */"); // END KGU 2015-10-18 insertBlockHeading(_root, "public class " + _procName, _indent); code.add(_indent); insertComment( "TODO: Declare and initialise class and member variables here", _indent + this.getIndent()); code.add(_indent); code.add(_indent + this.getIndent() + "/**"); code.add(_indent + this.getIndent() + " * @param args"); code.add(_indent + this.getIndent() + " */"); insertBlockHeading( _root, "public static void Main(string[] args)", _indent + this.getIndent()); code.add(""); } else { insertBlockComment(_root.getComment(), _indent + this.getIndent(), "/**", " * ", null); if (_resultType != null || this.returns || this.isFunctionNameSet || this.isResultSet) { insertBlockComment(_paramNames, _indent + this.getIndent(), null, " * @param ", null); code.add(_indent + this.getIndent() + " * @return "); code.add(_indent + this.getIndent() + " */"); _resultType = transformType(_resultType, "int"); } else { insertBlockComment(_paramNames, _indent + this.getIndent(), null, " * @param ", " */"); _resultType = "void"; } // START KGU#178 2016-07-20: Enh. #160 - insert called subroutines as private // String fnHeader = "public static " + _resultType + " " + _procName + "("; String fnHeader = (topLevel ? "public" : "private") + " static " + _resultType + " " + _procName + "("; // END KGU#178 2016-07-20 for (int p = 0; p < _paramNames.count(); p++) { if (p > 0) fnHeader += ", "; fnHeader += (transformType(_paramTypes.get(p), "/*type?*/") + " " + _paramNames.get(p)).trim(); } fnHeader += ")"; insertBlockHeading(_root, fnHeader, _indent + this.getIndent()); } return _indent + this.getIndent() + this.getIndent(); }
/** * We try our very best to create a working loop from a FOR-IN construct This will only work, * however, if we can get reliable information about the size of the value list, which won't be * the case if we obtain it e.g. via a variable. * * @param _for - the element to be exported * @param _indent - the current indentation level * @return true iff the method created some loop code (sensible or not) */ protected boolean generateForInCode(For _for, String _indent) { boolean isDisabled = _for.isDisabled(); // We simply use the range-based loop of Java (as far as possible) String var = _for.getCounterVar(); String valueList = _for.getValueList(); StringList items = this.extractForInListItems(_for); String indent = _indent; String itemType = null; if (items != null) { valueList = "{" + items.concatenate(", ") + "}"; // Good question is: how do we guess the element type and what do we // do if items are heterogenous? We will just try three types: int, // double and String, and if none of them match we add a TODO comment. int nItems = items.count(); boolean allInt = true; boolean allDouble = true; boolean allString = true; for (int i = 0; i < nItems; i++) { String item = items.get(i); if (allInt) { try { Integer.parseInt(item); } catch (NumberFormatException ex) { allInt = false; } } if (allDouble) { try { Double.parseDouble(item); } catch (NumberFormatException ex) { allDouble = false; } } if (allString) { allString = item.startsWith("\"") && item.endsWith("\"") && !item.substring(1, item.length() - 1).contains("\""); } } if (allInt) itemType = "int"; else if (allDouble) itemType = "double"; else if (allString) itemType = "char*"; String arrayName = "array20160322"; // Extra block to encapsulate the additional variable declarations addCode("{", _indent, isDisabled); indent += this.getIndent(); if (itemType == null) { itemType = "object"; this.insertComment( "TODO: Find a more specific item type than object and/or prepare the elements of the array", indent); } addCode( itemType + "[] " + arrayName + " = " + transform(valueList, false) + ";", indent, isDisabled); valueList = arrayName; } else { itemType = "object"; this.insertComment( "TODO: Find a more specific item type than object and/or prepare the elements of the array", indent); valueList = transform(valueList, false); } // Creation of the loop header insertBlockHeading(_for, "foreach (" + itemType + " " + var + " in " + valueList + ")", indent); // Add the loop body as is generateCode(_for.q, indent + this.getIndent()); // Accomplish the loop insertBlockTail(_for, null, indent); if (items != null) { addCode("}", _indent, isDisabled); } return true; }