Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00033 #include <acado/code_generation/export_for_loop.hpp>
00034
00035 #include <sstream>
00036
00037 BEGIN_NAMESPACE_ACADO
00038
00039 using namespace std;
00040
00041
00042
00043
00044
00045
00046 ExportForLoop::ExportForLoop( const ExportIndex& _loopVariable,
00047 const ExportIndex& _startValue,
00048 const ExportIndex& _finalValue,
00049 const ExportIndex& _increment,
00050 bool _doLoopUnrolling
00051 ) : ExportStatementBlock( ),
00052 loopVariable( _loopVariable ),
00053 startValue( _startValue ),
00054 finalValue( _finalValue ),
00055 increment( _increment ),
00056 doLoopUnrolling( _doLoopUnrolling )
00057 {
00058 sanityCheck();
00059 }
00060
00061
00062 ExportForLoop::ExportForLoop( const ExportForLoop& arg ) : ExportStatementBlock( arg ),
00063 loopVariable( arg.loopVariable ),
00064 startValue( arg.startValue ),
00065 finalValue( arg.finalValue ),
00066 increment( arg.increment ),
00067 doLoopUnrolling( arg.doLoopUnrolling )
00068 {
00069 }
00070
00071
00072 ExportForLoop::~ExportForLoop( )
00073 {
00074 clear( );
00075 }
00076
00077
00078 ExportForLoop& ExportForLoop::operator=( const ExportForLoop& arg )
00079 {
00080 if ( this != &arg )
00081 {
00082 ExportStatementBlock::operator=( arg );
00083 init(arg.loopVariable, arg.startValue, arg.finalValue, arg.increment, arg.doLoopUnrolling);
00084 }
00085
00086 return *this;
00087 }
00088
00089
00090 ExportStatement* ExportForLoop::clone( ) const
00091 {
00092 return new ExportForLoop( *this );
00093 }
00094
00095
00096 returnValue ExportForLoop::init( const ExportIndex& _loopVariable,
00097 const ExportIndex& _startValue,
00098 const ExportIndex& _finalValue,
00099 const ExportIndex& _increment,
00100 bool _doLoopUnrolling
00101 )
00102 {
00103 clear();
00104
00105 loopVariable = _loopVariable;
00106 startValue = _startValue;
00107 finalValue = _finalValue;
00108 increment = _increment;
00109 doLoopUnrolling = _doLoopUnrolling;
00110
00111 return SUCCESSFUL_RETURN;
00112 }
00113
00114
00115
00116
00117 returnValue ExportForLoop::exportDataDeclaration( std::ostream& stream,
00118 const std::string& _realString,
00119 const std::string& _intString,
00120 int _precision
00121 ) const
00122 {
00123 return SUCCESSFUL_RETURN;
00124 }
00125
00126
00127 returnValue ExportForLoop::exportCode( std::ostream& stream,
00128 const std::string& _realString,
00129 const std::string& _intString,
00130 int _precision
00131 ) const
00132 {
00133 returnValue status = sanityCheck();
00134 if (status != SUCCESSFUL_RETURN)
00135 return status;
00136
00137 if (startValue.isGiven() == true && finalValue.isGiven() == true)
00138 if (startValue.getGivenValue() == finalValue.getGivenValue())
00139 return SUCCESSFUL_RETURN;
00140
00141 if ( doLoopUnrolling == false )
00142 {
00143 stream << "for (" << loopVariable.get() << " = " << startValue.get() << "; ";
00144
00145 if (increment.isGiven() == true && increment.getGivenValue() == -1)
00146 stream << finalValue.get() << " < " << loopVariable.get() << "; ";
00147 else
00148 stream << loopVariable.get() << " < " << finalValue.get() << "; ";
00149
00150 if (increment.isGiven() == true)
00151 {
00152 switch ( increment.getGivenValue() )
00153 {
00154 case 1:
00155 stream << "++" << loopVariable.get();
00156 break;
00157
00158 case -1:
00159 stream << "--" << loopVariable.get();
00160 break;
00161
00162 default:
00163 stream << loopVariable.get() << " += " << increment.getGivenValue();
00164 break;
00165 }
00166 }
00167 else
00168 {
00169 stream << loopVariable.get() << " += " << increment.get();
00170 }
00171
00172 stream << ")" << endl << "{" << endl;
00173
00174 ExportStatementBlock::exportCode(stream, _realString, _intString, _precision);
00175
00176 stream << "}\n";
00177 }
00178
00179 return SUCCESSFUL_RETURN;
00180 }
00181
00182
00183
00184 ExportForLoop& ExportForLoop::unrollLoop( )
00185 {
00186 doLoopUnrolling = true;
00187 return *this;
00188 }
00189
00190
00191 ExportForLoop& ExportForLoop::keepLoop( )
00192 {
00193 doLoopUnrolling = false;
00194 return *this;
00195 }
00196
00197 ExportForLoop& ExportForLoop::allocate(MemoryAllocatorPtr allocator)
00198 {
00199
00200
00201
00202
00203 StatementPtrArray::const_iterator it = statements.begin();
00204 for(; it != statements.end(); ++it)
00205 (*it)->allocate( allocator );
00206
00207 return *this;
00208 }
00209
00210
00211
00212
00213
00214
00215 returnValue ExportForLoop::clear( )
00216 {
00217 return SUCCESSFUL_RETURN;
00218 }
00219
00220
00221
00222
00223 returnValue ExportForLoop::sanityCheck() const
00224 {
00225 if (doLoopUnrolling == true)
00226 return ACADOERRORTEXT(RET_NOT_IMPLEMENTED_YET, "Loop unrolling is not yet implemented");
00227
00228 if (startValue.isGiven() == true && finalValue.isGiven() == true && increment.isGiven() == true)
00229 {
00230 if ( ( startValue.getGivenValue() > finalValue.getGivenValue() ) && ( increment.getGivenValue() >= 0 ) )
00231 return ACADOERRORTEXT(RET_INVALID_ARGUMENTS, "Export for loop arguments are invalid");
00232
00233 if ( ( startValue.getGivenValue() < finalValue.getGivenValue() ) && ( increment.getGivenValue() <= 0 ) )
00234 return ACADOERRORTEXT(RET_INVALID_ARGUMENTS, "Export for loop arguments are invalid");
00235 }
00236
00237 return SUCCESSFUL_RETURN;
00238 }
00239
00240
00241 CLOSE_NAMESPACE_ACADO
00242
00243