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 boost::copy_graph( fn->getGraph(), *graph,
00309 boost::vertex_copy( GraphVertexCopier( fn->getGraph(), *graph, replacementdss ) ).
00310 edge_copy( GraphEdgeCopier( fn->getGraph(), *graph, replacementdss ) ) );
00311
00312
00313 for (unsigned int i=0; i < newlist.size(); ++i)
00314 delete newlist[i];
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 graph_traits<Graph>::vertex_iterator v1,v2, vc;
00325 tie(v1,v2) = vertices(*graph);
00326 boost::property_map<Graph, vertex_exec_t>::type
00327 vmap = get(vertex_exec, *graph);
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 Vertex funcStart=*
00347 find_if(v1, v2,
00348 bind2nd( finder<boost::property_map<Graph, vertex_exec_t>::type>() ,
00349 std::make_pair( vmap, int(VertexNode::func_start_node)) ) );
00350 Vertex funcExit=*
00351 find_if(v1, v2,
00352 bind2nd( finder<boost::property_map<Graph, vertex_exec_t>::type>() ,
00353 std::make_pair( vmap, int(VertexNode::func_exit_node)) ) );
00354
00355
00356 vmap[funcStart] = VertexNode::normal_node;
00357 vmap[funcExit] = VertexNode::normal_node;
00358
00359 addConditionEdge( cond, funcStart );
00360 connectToNext( funcExit, new ConditionTrue );
00361
00362 return funcExit;
00363
00364
00365
00366
00367 }
00368
00369 FunctionGraphBuilder::CommandNode FunctionGraphBuilder::setFunction( FunctionGraphPtr fn,
00370 std::vector<DataSourceBase::shared_ptr> fnargs )
00371 {
00380 return appendFunction( new ConditionTrue, fn, fnargs) ;
00381 }
00382
00383 void FunctionGraphBuilder::startIfStatement( ConditionInterface* cond, int linenumber )
00384 {
00385
00386
00387
00388
00389
00390
00391
00392 CommandNode else_node = add_vertex( *graph );
00393 put(vertex_exec, *graph, else_node, VertexNode::normal_node );
00394 branch_stack.push( else_node );
00395 CommandNode after_else_node = add_vertex( *graph );
00396 put(vertex_exec, *graph, after_else_node, VertexNode::normal_node );
00397 branch_stack.push( after_else_node );
00398
00399
00400
00401 addConditionEdge( cond, next );
00402
00403 addConditionEdge( new ConditionTrue(), else_node );
00404 proceedToNext(linenumber);
00405 }
00406
00407 void FunctionGraphBuilder::endIfBlock(int linenumber){
00408
00409
00410
00411 CommandNode after_else_node = branch_stack.top();
00412 addConditionEdge( new ConditionTrue(), after_else_node );
00413 branch_stack.pop();
00414
00415 moveTo( branch_stack.top(), next, linenumber );
00416 branch_stack.pop();
00417
00418 branch_stack.push( after_else_node );
00419 }
00420
00421
00422 void FunctionGraphBuilder::endElseBlock(int linenumber) {
00423
00424 CommandNode after_else_node = branch_stack.top();
00425 branch_stack.pop();
00426 addConditionEdge( new ConditionTrue(), after_else_node );
00427
00428 moveTo( after_else_node, next, linenumber );
00429 }
00430
00431 void FunctionGraphBuilder::startWhileStatement( ConditionInterface* cond, int linenumber )
00432 {
00433
00434
00435 CommandNode after_while_node = add_vertex( *graph );
00436 put(vertex_exec, *graph, after_while_node, VertexNode::normal_node );
00437 branch_stack.push( after_while_node );
00438 break_stack.push( after_while_node );
00439 branch_stack.push( build );
00440
00441 addConditionEdge( cond, next );
00442
00443 addConditionEdge( new ConditionTrue(), after_while_node );
00444 proceedToNext(linenumber);
00445 }
00446
00447 void FunctionGraphBuilder::endWhileBlock(int linenumber)
00448 {
00449 CommandNode start_of_while = branch_stack.top();
00450 branch_stack.pop();
00451
00452 addConditionEdge( new ConditionTrue(), start_of_while );
00453 CommandNode after_while_node = branch_stack.top();
00454 branch_stack.pop();
00455 break_stack.pop();
00456 moveTo( after_while_node, next, linenumber );
00457 }
00458
00459 bool FunctionGraphBuilder::inLoop()
00460 {
00461 return break_stack.size() != 0;
00462 }
00463
00464 bool FunctionGraphBuilder::breakLoop()
00465 {
00466 if ( !inLoop() )
00467 return false;
00468
00469
00470 addConditionEdge( new ConditionTrue(), break_stack.top() );
00471 return true;
00472 }
00473
00474 #if 0
00475 void FunctionGraphBuilder::prependCommand( ActionInterface* command, int line_nr )
00476 {
00477 CommandNode previousstart = start;
00478 start = add_vertex( program );
00479 boost::property_map<Graph, vertex_exec_t>::type
00480 vmap = get(vertex_exec, program);
00481 put( vmap, start, get( vmap, previousstart ) );
00482 put( vmap, previousstart, VertexNode::normal_node );
00483 boost::property_map<Graph, vertex_command_t>::type
00484 cmap = get( vertex_command, program );
00485 VertexNode vnode( command );
00486 vnode.setLineNumber( line_nr );
00487 put( cmap, start, vnode );
00488 add_edge(start, previousstart, EdgeCondition(new ConditionTrue), program);
00489 if ( build == previousstart )
00490 build = start;
00491
00492
00493 boost::property_map<Graph, vertex_index_t>::type indexmap =
00494 get( vertex_index, *graph );
00495 boost::graph_traits<Graph>::vertex_iterator v, vend;
00496 int index = 0;
00497 for ( tie( v, vend ) = vertices( *graph ); v != vend; ++v )
00498 indexmap[*v] = index++;
00499 }
00500 #endif
00501
00502 }
00503