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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "FunctionGraphBuilder.hpp"
00041 #include "CommandComposite.hpp"
00042 #include "../base/AttributeBase.hpp"
00043 #include "../internal/DataSource.hpp"
00044
00045 #include "../FactoryExceptions.hpp"
00046 #include "GraphCopier.hpp"
00047
00048 #include "CommandNOP.hpp"
00049 #include "ConditionFalse.hpp"
00050 #include "ConditionTrue.hpp"
00051 #include "ConditionTrue.hpp"
00052 #include <boost/graph/copy.hpp>
00053 #include <utility>
00054
00055 #include <iostream>
00056
00057 namespace RTT {
00058 using namespace detail;
00059 using namespace boost;
00060 using namespace std;
00061
00062
00063
00064
00065 FunctionGraphBuilder::FunctionGraphBuilder()
00066 : graph( 0 )
00067 {
00068 }
00069
00070 FunctionGraphBuilder::~FunctionGraphBuilder()
00071 {
00072 }
00073
00074 FunctionGraphPtr FunctionGraphBuilder::startFunction(const std::string& fname)
00075 {
00076
00077
00078 func.reset( new FunctionGraph( fname, true ) );
00079 graph = &func->getGraph();
00080 build = func->startNode();
00081 next = add_vertex( *graph );
00082 put( vertex_exec, *graph, next, VertexNode::normal_node );
00083 return func;
00084 }
00085
00086 void FunctionGraphBuilder::returnFunction( ConditionInterface* cond, int line )
00087 {
00088
00089
00090 add_edge(build, func->exitNode(), EdgeCondition(cond), *graph);
00091 }
00092
00093 FunctionGraphPtr FunctionGraphBuilder::getFunction()
00094 {
00095 return func;
00096 }
00097
00098 FunctionGraphPtr FunctionGraphBuilder::endFunction( int endline )
00099 {
00100
00101 boost::property_map<Graph, vertex_command_t>::type
00102 cmap = get(vertex_command, *graph);
00103 cmap[func->exitNode()].setLineNumber( endline );
00104
00105
00106
00107
00108
00109 remove_vertex( build, *graph );
00110 remove_vertex( next, *graph );
00111
00112 func->finish();
00113 func->reset();
00114
00115 FunctionGraphPtr tfunc = func;
00116 func.reset();
00117 return tfunc;
00118 }
00119
00120 FunctionGraphBuilder::CommandNode FunctionGraphBuilder::addCommand( ConditionInterface* cond, ActionInterface* com )
00121 {
00122 add_edge(build, next, EdgeCondition(cond), *graph);
00123 build = next;
00124 setCommand(com);
00125 next = add_vertex( *graph );
00126 put( vertex_exec, *graph, next, VertexNode::normal_node );
00127 return next;
00128 }
00129
00130 void FunctionGraphBuilder::addConditionEdge( ConditionInterface* cond, CommandNode vert )
00131 {
00132 add_edge(build, vert, EdgeCondition(cond), *graph);
00133 }
00134
00135 void FunctionGraphBuilder::closeConditionEdge( CommandNode vert, ConditionInterface* cond )
00136 {
00137 add_edge(vert, build, EdgeCondition(cond), *graph);
00138 }
00139
00140 FunctionGraphBuilder::CommandNode FunctionGraphBuilder::moveTo( CommandNode _build, CommandNode _next, int linenumber )
00141 {
00142 this->setLineNumber( linenumber );
00143 CommandNode old = build;
00144 build = _build;
00145 next = _next;
00146 return old;
00147 }
00148
00149 ActionInterface* FunctionGraphBuilder::getCommand( CommandNode cn )
00150 {
00151
00152 boost::property_map<Graph, vertex_command_t>::type
00153 cmap = get(vertex_command, *graph);
00154
00155 return cmap[cn].getCommand();
00156 }
00157
00158 void FunctionGraphBuilder::setCommand( ActionInterface* comm )
00159 {
00160 this->setCommand(build, comm);
00161 }
00162
00163 void FunctionGraphBuilder::setCommand(CommandNode cn, ActionInterface* comm )
00164 {
00165
00166 boost::property_map<Graph, vertex_command_t>::type
00167 cmap = get(vertex_command, *graph);
00168
00169 delete cmap[cn].setCommand( comm );
00170 }
00171
00172 void FunctionGraphBuilder::setName(const std::string& pname) {
00173 func->setName(pname);
00174 }
00175
00176 FunctionGraphBuilder::CommandNode FunctionGraphBuilder::proceedToNext( ConditionInterface* cond, int this_line )
00177 {
00178 add_edge(build, next, EdgeCondition(cond), *graph);
00179 return proceedToNext( this_line );
00180 }
00181
00182 FunctionGraphBuilder::CommandNode FunctionGraphBuilder::proceedToNext( int this_line )
00183 {
00184 if ( this_line )
00185 this->setLineNumber( this_line );
00186 build = next;
00187 next = add_vertex( *graph );
00188 put(vertex_exec, *graph, next, VertexNode::normal_node );
00189 return build;
00190 }
00191
00192 void FunctionGraphBuilder::connectToNext( CommandNode v, ConditionInterface* cond )
00193 {
00194 add_edge( v, next, EdgeCondition(cond), *graph);
00195 }
00196
00197 FunctionGraphBuilder::CommandNode FunctionGraphBuilder::buildNode() const
00198 {
00199 return build;
00200 }
00201
00202 size_t FunctionGraphBuilder::buildEdges() const
00203 {
00204 return out_degree( build, *graph );
00205 }
00206
00207 FunctionGraphBuilder::CommandNode FunctionGraphBuilder::nextNode() const
00208 {
00209 return next;
00210 }
00211
00212 void FunctionGraphBuilder::setLineNumber( int line )
00213 {
00214 boost::property_map<Graph, vertex_command_t>::type
00215 cmap = get(vertex_command, *graph);
00216 cmap[build].setLineNumber( line );
00217 }
00218
00219
00220 template< class _Map >
00221 struct finder {
00222 typedef FunctionGraphBuilder::Vertex first_argument_type ;
00223 typedef std::pair<_Map, int> second_argument_type ;
00224 typedef bool result_type;
00225 bool operator()(const FunctionGraphBuilder::Vertex& v,
00226 const std::pair<_Map, int>& to_find ) const
00227 {
00228
00229 return to_find.first[v] == to_find.second;
00230 }
00231 };
00232
00233 FunctionGraphBuilder::CommandNode FunctionGraphBuilder::appendFunction( ConditionInterface* cond, FunctionGraphPtr fn,
00234 std::vector<DataSourceBase::shared_ptr> fnargs )
00235 {
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 boost::property_map<Graph, vertex_index_t>::type indexmap =
00249 get( vertex_index, *graph );
00250 boost::graph_traits<Graph>::vertex_iterator v, vend;
00251 int index = 0;
00252 for ( tie( v, vend ) = vertices( *graph ); v != vend; ++v )
00253 indexmap[*v] = index++;
00254
00255
00256 std::vector<AttributeBase*> origlist = fn->getArguments();
00257 if ( fnargs.size() != origlist.size() ) {
00258 #ifndef ORO_EMBEDDED
00259 throw wrong_number_of_args_exception( origlist.size(), fnargs.size() );
00260 #else
00261 return buildNode();
00262 #endif
00263 }
00264
00265
00266 std::map<const DataSourceBase*, DataSourceBase*> replacementdss;
00267 std::vector<AttributeBase*> newlist;
00268 for (unsigned int i=0; i < origlist.size(); ++i)
00269 newlist.push_back( origlist[i]->copy( replacementdss, false ) );
00270
00271
00272
00273 CommandComposite* icom= new CommandComposite();
00274 std::vector<DataSourceBase::shared_ptr>::const_iterator dit = fnargs.begin();
00275 std::vector<AttributeBase*>::const_iterator tit = newlist.begin();
00276 #ifndef ORO_EMBEDDED
00277 try {
00278 for (; dit != fnargs.end(); ++dit, ++tit)
00279 icom->add( (*tit)->getDataSource()->updateAction( dit->get() ) );
00280 }
00281 catch( const bad_assignment& ) {
00282
00283 for (unsigned int i=0; i < newlist.size(); ++i)
00284 delete newlist[i];
00285 delete icom;
00286 int parnb = (dit - fnargs.begin());
00287 throw wrong_types_of_args_exception(parnb, (*tit)->getDataSource()->getType() ,(*dit)->getType() );
00288 }
00289 #else
00290 for (; dit != fnargs.end(); ++dit, ++tit) {
00291 ActionInterface* ret = (*tit)->getDataSource()->updateAction( dit->get() );
00292 if (ret)
00293 icom->add( ret );
00294 else {
00295
00296 for (unsigned int i=0; i < newlist.size(); ++i)
00297 delete newlist[i];
00298 delete icom;
00299 return buildNode();
00300 }
00301 }
00302 #endif
00303
00304
00305 assert( dynamic_cast<CommandNOP*>( this->getCommand(build) ));
00306 this->setCommand( icom );
00307
00308 GraphVertexCopier gvc( fn->getGraph(), *graph, replacementdss );
00309 GraphEdgeCopier gec( fn->getGraph(), *graph, replacementdss );
00310
00311
00312 boost::copy_graph( fn->getGraph(), *graph, boost::vertex_copy( gvc ).edge_copy( gec ) );
00313
00314
00315
00316
00317 for (unsigned int i=0; i < newlist.size(); ++i)
00318 delete newlist[i];
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 graph_traits<Graph>::vertex_iterator v1,v2, vc;
00329 tie(v1,v2) = vertices(*graph);
00330 boost::property_map<Graph, vertex_exec_t>::type
00331 vmap = get(vertex_exec, *graph);
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 Vertex funcStart=*
00351 find_if(v1, v2,
00352 bind2nd( finder<boost::property_map<Graph, vertex_exec_t>::type>() ,
00353 std::make_pair( vmap, int(VertexNode::func_start_node)) ) );
00354 Vertex funcExit=*
00355 find_if(v1, v2,
00356 bind2nd( finder<boost::property_map<Graph, vertex_exec_t>::type>() ,
00357 std::make_pair( vmap, int(VertexNode::func_exit_node)) ) );
00358
00359
00360 vmap[funcStart] = VertexNode::normal_node;
00361 vmap[funcExit] = VertexNode::normal_node;
00362
00363 addConditionEdge( cond, funcStart );
00364 connectToNext( funcExit, new ConditionTrue );
00365
00366 return funcExit;
00367
00368
00369
00370
00371 }
00372
00373 FunctionGraphBuilder::CommandNode FunctionGraphBuilder::setFunction( FunctionGraphPtr fn,
00374 std::vector<DataSourceBase::shared_ptr> fnargs )
00375 {
00384 return appendFunction( new ConditionTrue, fn, fnargs) ;
00385 }
00386
00387 void FunctionGraphBuilder::startIfStatement( ConditionInterface* cond, int linenumber )
00388 {
00389
00390
00391
00392
00393
00394
00395
00396 CommandNode else_node = add_vertex( *graph );
00397 put(vertex_exec, *graph, else_node, VertexNode::normal_node );
00398 branch_stack.push( else_node );
00399 CommandNode after_else_node = add_vertex( *graph );
00400 put(vertex_exec, *graph, after_else_node, VertexNode::normal_node );
00401 branch_stack.push( after_else_node );
00402
00403
00404
00405 addConditionEdge( cond, next );
00406
00407 addConditionEdge( new ConditionTrue(), else_node );
00408 proceedToNext(linenumber);
00409 }
00410
00411 void FunctionGraphBuilder::endIfBlock(int linenumber){
00412
00413
00414
00415 CommandNode after_else_node = branch_stack.top();
00416 addConditionEdge( new ConditionTrue(), after_else_node );
00417 branch_stack.pop();
00418
00419 moveTo( branch_stack.top(), next, linenumber );
00420 branch_stack.pop();
00421
00422 branch_stack.push( after_else_node );
00423 }
00424
00425
00426 void FunctionGraphBuilder::endElseBlock(int linenumber) {
00427
00428 CommandNode after_else_node = branch_stack.top();
00429 branch_stack.pop();
00430 addConditionEdge( new ConditionTrue(), after_else_node );
00431
00432 moveTo( after_else_node, next, linenumber );
00433 }
00434
00435 void FunctionGraphBuilder::startWhileStatement( ConditionInterface* cond, int linenumber )
00436 {
00437
00438
00439 CommandNode after_while_node = add_vertex( *graph );
00440 put(vertex_exec, *graph, after_while_node, VertexNode::normal_node );
00441 branch_stack.push( after_while_node );
00442 break_stack.push( after_while_node );
00443 branch_stack.push( build );
00444
00445 addConditionEdge( cond, next );
00446
00447 addConditionEdge( new ConditionTrue(), after_while_node );
00448 proceedToNext(linenumber);
00449 }
00450
00451 void FunctionGraphBuilder::endWhileBlock(int linenumber)
00452 {
00453 CommandNode start_of_while = branch_stack.top();
00454 branch_stack.pop();
00455
00456 addConditionEdge( new ConditionTrue(), start_of_while );
00457 CommandNode after_while_node = branch_stack.top();
00458 branch_stack.pop();
00459 break_stack.pop();
00460 moveTo( after_while_node, next, linenumber );
00461 }
00462
00463 bool FunctionGraphBuilder::inLoop()
00464 {
00465 return break_stack.size() != 0;
00466 }
00467
00468 bool FunctionGraphBuilder::breakLoop()
00469 {
00470 if ( !inLoop() )
00471 return false;
00472
00473
00474 addConditionEdge( new ConditionTrue(), break_stack.top() );
00475 return true;
00476 }
00477
00478 #if 0
00479 void FunctionGraphBuilder::prependCommand( ActionInterface* command, int line_nr )
00480 {
00481 CommandNode previousstart = start;
00482 start = add_vertex( program );
00483 boost::property_map<Graph, vertex_exec_t>::type
00484 vmap = get(vertex_exec, program);
00485 put( vmap, start, get( vmap, previousstart ) );
00486 put( vmap, previousstart, VertexNode::normal_node );
00487 boost::property_map<Graph, vertex_command_t>::type
00488 cmap = get( vertex_command, program );
00489 VertexNode vnode( command );
00490 vnode.setLineNumber( line_nr );
00491 put( cmap, start, vnode );
00492 add_edge(start, previousstart, EdgeCondition(new ConditionTrue), program);
00493 if ( build == previousstart )
00494 build = start;
00495
00496
00497 boost::property_map<Graph, vertex_index_t>::type indexmap =
00498 get( vertex_index, *graph );
00499 boost::graph_traits<Graph>::vertex_iterator v, vend;
00500 int index = 0;
00501 for ( tie( v, vend ) = vertices( *graph ); v != vend; ++v )
00502 indexmap[*v] = index++;
00503 }
00504 #endif
00505
00506 }
00507