Expr Ast_Import::_parse_in( ParsingContext &context ) const { return context.ret_error( "TODO: _parse_in", false, __FILE__, __LINE__ ); }
Expr Ast_While::_parse_in( ParsingContext &context ) const { // watch modified variables IpSnapshot nsv( ip->ip_snapshot ); // we repeat until there are no external modified values int ne = ip->error_list.size(); std::map<Expr,Expr> unknowns; for( unsigned old_nsv_size = 0, cpt = 0; ; old_nsv_size = nsv.rooms.size(), ++cpt ) { if ( cpt == 20 ) return context.ret_error( "infinite loop during while parsing" ); ParsingContext wh_scope( &context, 0, "while_" + to_string( ok ) ); wh_scope.cont = true; ok->parse_in( wh_scope ); if ( ne != ip->error_list.size() ) return Expr(); // if no new modified variables if ( old_nsv_size == nsv.rooms.size() ) break; // replace each modified variable to a new unknown variables // (to avoid simplifications during the next round) for( std::pair<Inst *const,Expr> &it : nsv.rooms ) { Expr unk = unknown_inst( it.second->type(), cpt ); unknowns[ it.first ] = unk; const_cast<Inst *>( it.first )->set( unk, true ); } nsv.undo_parsing_contexts(); } // corr table (output number -> input number) // -> find if Unknown inst are used to compute the outputs ++Inst::cur_op_id; for( std::pair<Inst *const,Expr> &it : nsv.rooms ) const_cast<Inst *>( it.first )->get( context.cond )->mark_children(); int cpt = 0; Vec<int> corr; Vec<Type *> inp_types; for( std::pair<Inst *const,Expr> &it : nsv.rooms ) { if ( unknowns[ it.first ]->op_id == Inst::cur_op_id ) { corr << cpt++; inp_types << it.second->type(); } else corr << -1; } // prepare a while inp (for initial values of variables modified in the loop) Expr winp = while_inp( inp_types ); // set winp[...] as initial values of modified variables cpt = 0; for( std::pair<Inst *const,Expr> &it : nsv.rooms ) { int num_inp = corr[ cpt++ ]; if ( num_inp >= 0 ) const_cast<Inst *>( it.first )->set( get_nout( winp, num_inp ), true ); else const_cast<Inst *>( it.first )->set( it.second, true ); } nsv.undo_parsing_contexts(); // relaunch the while inst ParsingContext wh_scope( &context, 0, "while_" + to_string( ok ) ); wh_scope.cont = true; ok->parse_in( wh_scope ); if ( wh_scope.cont->always( false ) ) { ip->ip_snapshot = nsv.prev; } else { // make the while instruction Vec<Expr> out_exprs; for( std::pair<Inst *const,Expr> &it : nsv.rooms ) out_exprs << const_cast<Inst *>( it.first )->get( context.cond ); Expr wout = while_out( out_exprs, wh_scope.cont ); cpt = 0; Vec<Expr> inp_exprs; for( std::pair<Inst *const,Expr> &it : nsv.rooms ) if ( corr[ cpt++ ] >= 0 ) inp_exprs << it.second->simplified( context.cond ); Expr wins = while_inst( inp_exprs, winp, wout, corr ); ip->ip_snapshot = nsv.prev; // replace changed variable by while_inst outputs cpt = 0; for( std::pair<Inst *const,Expr> &it : nsv.rooms ) const_cast<Inst *>( it.first )->set( get_nout( wins, cpt++ ), context.cond ); } // break(s) to transmit ? for( ParsingContext::RemBreak rb : wh_scope.rem_breaks ) context.BREAK( rb.count, rb.cond ); return ip->void_var(); }