sa_statements.cc

Go to the documentation of this file.
00001 /*
00002    The lestes compiler suite
00003    Copyright (C) 2002, 2003, 2004, 2005 Miroslav Tichy
00004    Copyright (C) 2002, 2003, 2004, 2005 Petr Zika
00005    Copyright (C) 2002, 2003, 2004, 2005 Vojtech Hala
00006    Copyright (C) 2002, 2003, 2004, 2005 Jiri Kosina
00007    Copyright (C) 2002, 2003, 2004, 2005 Pavel Sanda
00008    Copyright (C) 2002, 2003, 2004, 2005 Jan Zouhar
00009    Copyright (C) 2002, 2003, 2004, 2005 Rudolf Thomas
00010 
00011    This program is free software; you can redistribute it and/or modify
00012    it under the terms of the GNU General Public License as published by
00013    the Free Software Foundation; version 2 of the License.
00014 
00015    This program is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019 
00020    See the full text of the GNU General Public License version 2, and
00021    the limitations in the file doc/LICENSE.
00022 
00023    By accepting the license the licensee waives any and all claims
00024    against the copyright holder(s) related in whole or in part to the
00025    work, its use, and/or the inability to use it.
00026  
00027  */
00028 /*!
00029         \file
00030         \brief SS statements creation called from parser.y
00031         \author egg
00032 */
00033 
00034 #include <lestes/std/list.hh>
00035 #include <lestes/std/source_location.hh>
00036 #include <lestes/lang/cplus/sem/declaration_broadcasting.hh>
00037 #include <lestes/lang/cplus/sem/sa_statements.g.hh>
00038 #include <lestes/lang/cplus/sem/sa_context.g.hh>
00039 #include <lestes/lang/cplus/sem/sa_decl_seq_compound_pair_creator.g.hh>
00040 #include <lestes/lang/cplus/sem/sa_declaration_specifiers.g.hh>
00041 #include <lestes/lang/cplus/sem/sa_deconstruct_spse.g.hh>
00042 #include <lestes/lang/cplus/sem/as_expr.g.hh>
00043 #include <lestes/lang/cplus/sem/as_decl.g.hh>
00044 #include <lestes/lang/cplus/sem/as_other.g.hh>
00045 #include <lestes/lang/cplus/sem/as_statements.g.hh>
00046 #include <lestes/lang/cplus/sem/or_or.g.hh>
00047 #include <lestes/lang/cplus/sem/or_ics.g.hh>
00048 #include <lestes/lang/cplus/sem/ss_statement.g.hh>
00049 #include <lestes/lang/cplus/sem/ss_declaration.g.hh>
00050 #include <lestes/lang/cplus/sem/ss_decl_name.g.hh>
00051 #include <lestes/lang/cplus/sem/ss_literal_info.g.hh>
00052 #include <lestes/lang/cplus/sem/ss_type.g.hh>
00053 #include <lestes/lang/cplus/sem/ss_type_builtin.g.hh>
00054 #include <lestes/lang/cplus/sem/ss_misc.g.hh>
00055 #include <lestes/lang/cplus/syn/token.hh>
00056 #include <lestes/lang/cplus/syn/manager.hh>
00057 #include <lestes/lang/cplus/sem/sa_loggers.hh>
00058 #include <lestes/lang/cplus/sem/visitor.v.g.hh>
00059 #include <lestes/msg/logger.hh>
00060 #include <lestes/msg/logger_util.hh>
00061 #include <lestes/lang/cplus/sem/sa_statements.m.hh>
00062 #include <cstdlib>
00063 
00064 
00065 package(lestes);
00066 package(lang);
00067 package(cplus);
00068 package(sem);
00069 
00070 typedef ::lestes::std::list< srp< ss_sp > > sp_list;
00071 typedef ::lestes::std::list< srp< ss_label > > label_list;
00072 typedef ::lestes::std::list< srp< ss_expression > > expr_list;
00073 typedef ::lestes::std::list< srp< ss_statement > > stmt_list;
00074 typedef ::lestes::std::list< srp< ss_declaration > > decl_list;
00075 typedef ::lestes::std::source_location location;
00076 
00077 #define current_context sa_context_manager::instance()->current()
00078 #define current_ss      current_context->ss_get()
00079 #define current_as      current_context->as_get()
00080 #define current_sa      current_context->sa_get()
00081 #define current_decl_seq        current_ss->scope_get()
00082 #define current_compound        current_decl_seq->compound_stmt_get()
00083 #define current_statements      current_compound->statements_get()
00084 #define current_psp current_compound->destructor_sp_get()->psp_get()
00085 #define current_nsp current_compound->destructor_sp_get()
00086 
00087 /* if in disambiguation, bail out immediately.
00088  * this should be the first line in all actions called from parser.y */
00089 #define DISAMB if (::lestes::lang::cplus::syn::manager::in_disambiguation()) return
00090 
00091 // 2 new sequence points
00092 #define ALPHABETASPS(loc) \
00093         ptr<ss_sp> alpha = ss_sp::create(loc,current_psp,NULL,0);\
00094         ptr<ss_sp> beta = ss_sp::create(loc,alpha,current_nsp,0);\
00095         alpha->nsp_set(beta);\
00096         current_psp->nsp_set(alpha);\
00097         current_nsp->psp_set(beta);\
00098         ptr<sp_list> sps = sp_list::create();\
00099         sps->push_back(alpha);\
00100         sps->push_back(beta);
00101 
00102 ptr<sa_statements> sa_statements::the_instance = the_instance;
00103         
00104 ptr<sa_statements> sa_statements::instance()
00105 {
00106         if (the_instance) return the_instance;
00107         sa_statements_logger << "creating sa_statements instance\n" << msg::eolog;
00108         declaration_finished->attach(decl_stmt_listener::instance());
00109         return the_instance = new sa_statements(NULL,NULL);
00110 }
00111 
00112 void decl_stmt_listener::run(ptr<ss_declaration> decl)
00113 {
00114         DISAMB;
00115         sa_statements_logger << "object declaration\n" << msg::eolog;
00116         lassert(decl);
00117         decl->accept_ss_declaration_visitor(last_declaration_memorizer::instance());
00118 }
00119 
00120 void last_declaration_memorizer::default_action(ptr<ss_declaration> decl)
00121 {
00122         lassert(decl);
00123         sa_statements_logger << "non-object declaration => creating declaration statement\n" << msg::eolog;
00124         sa_statements::instance()->last_declaration_set(decl);
00125         ALPHABETASPS(decl->location_get());
00126         ptr<ss_decl_stmt> stmt = ss_decl_stmt::create(
00127                         decl->location_get(), // location
00128                         label_list::create(), // labels pointing at me
00129                         current_compound, // parent
00130                         alpha, // psp
00131                         beta, // nsp
00132                         sps, // list of SP
00133                         decl, // declaration
00134                         expr_list::create(), // args
00135                         ss_decl_stmt::IK_NOT_APPLY_INITIALIZATION // initializer kind
00136                         );
00137         current_statements->push_back(stmt);
00138 }
00139 
00140 void last_declaration_memorizer::visit_ss_object_declaration(ptr<ss_object_declaration> decl)
00141 {
00142         sa_statements::instance()->last_declaration_set(decl);
00143 }
00144 
00145 void sa_statements::declarator_simple(ptr<location> loc)
00146 {
00147         DISAMB;
00148         sa_statements_logger << "declarator simple -> inserting decl stmt\n" << msg::eolog;
00149         lassert(loc);
00150         lassert2(last_declaration,"declarator without declaration?");
00151         ALPHABETASPS(loc);
00152         ptr<ss_decl_stmt> stmt = ss_decl_stmt::create(
00153                         loc, // location
00154                         label_list::create(), // labels pointing at me
00155                         current_compound, // parent
00156                         alpha, // psp
00157                         beta, // nsp
00158                         sps, // list of SP
00159                         last_declaration_get(), // declaration
00160                         expr_list::create(), // args
00161                         ss_decl_stmt::IK_DEFAULT_INITIALIZATION // initializer kind
00162                         );
00163         current_statements->push_back(stmt);
00164 }
00165 
00166 void sa_statements::declarator_init(ptr<location> loc, ptr<as_initializer_clause> as)
00167 {
00168         DISAMB;
00169         sa_statements_logger << "declarator with initializer -> inserting decl stmt\n" << msg::eolog;
00170         lassert(as);
00171         lassert(loc);
00172         lassert2(last_declaration,"declarator without declaration?");
00173         ALPHABETASPS(loc);
00174         ptr<expr_list> args = initializer_clause_converter::create(
00175                         alpha,
00176                         beta,
00177                         sps,
00178                         last_declaration->type_get()
00179                         )->process(as);
00180         ptr<ss_decl_stmt> stmt = ss_decl_stmt::create(
00181                         loc, // location
00182                         label_list::create(), // labels pointing at me
00183                         current_compound, // parent
00184                         alpha, // psp
00185                         beta, // nsp
00186                         sps, // list of SP
00187                         last_declaration_get(), // declaration
00188                         args, // args
00189                         ss_decl_stmt::IK_COPY_INITIALIZATION // initializer kind
00190                         );
00191         current_statements->push_back(stmt);
00192 }
00193 
00194 void sa_statements::declarator_ctor(ptr<location> loc, ptr<as_expression_list> as)
00195 {
00196         DISAMB;
00197         sa_statements_logger << "declarator with constructor -> inserting decl stmt\n" << msg::eolog;
00198         lassert(as);
00199         lassert(!as->l_get()->empty());
00200         lassert(loc);
00201         lassert2(last_declaration,"declarator without declaration?");
00202         ptr<expr_list> args = expr_list::create();
00203         ALPHABETASPS(loc);
00204         ptr<ss_sp> psp = alpha;
00205         list< srp<as_expression> >::iterator i = as->l_get()->begin();
00206         for(; i != as->l_get()->end(); i++) {
00207                 // convert each expression
00208                 ptr<ss_expression> expr = sa_expression_converter::create(psp,beta,sps)->process(*i);
00209                 // the next one will be between beta and it's predecessor
00210                 psp = beta->psp_get();
00211                 // remember the expression
00212                 args->push_back(expr);
00213         }
00214         ptr<ss_decl_stmt> stmt = ss_decl_stmt::create(
00215                         loc, // location
00216                         label_list::create(), // labels pointing at me
00217                         current_compound, // parent
00218                         alpha, // psp
00219                         beta, // nsp
00220                         sps, // list of SP
00221                         last_declaration_get(), // declaration
00222                         args, // args
00223                         ss_decl_stmt::IK_DIRECT_INITIALIZATION // initializer kind
00224                         );
00225         current_statements->push_back(stmt);
00226 }
00227 
00228 void initializer_clause_converter::visit_as_initializer_clause_expression(ptr<as_initializer_clause_expression> as)
00229 {
00230         ptr<ss_expression> expr =
00231                 // allways require a conversion to target type
00232                 sa_expression_converter::create(psp,nsp,sps,type,NULL)->process(as->expression_get());
00233         result_set(expr_list::create());
00234         result_get()->push_back(expr);
00235 }
00236 
00237 void initializer_clause_converter::visit_as_initializer_clause_braced(ptr<as_initializer_clause_braced> as)
00238 {
00239         lassert(as);
00240         result_set(expr_list::create());
00241         ptr<ss_sp> actual_psp = nsp;
00242         ::lestes::std::list< srp< as_initializer_clause > >::iterator i = as->initializers_get()->begin();
00243         for(; i != as->initializers_get()->end(); i++) {
00244                 // convert recursively each sub-brace
00245                 ptr<expr_list> expressions =
00246                         initializer_clause_converter::create(actual_psp,nsp,sps,type)->process(*i);
00247                 // the next one will be between beta and it's predecessor
00248                 actual_psp = nsp->psp_get();
00249                 // append each expression to output
00250                 expr_list::iterator j = expressions->begin();
00251                 // FIXME! it's not quite OK to connect all of it into one list
00252                 for(; j != expressions->end(); j++){
00253                         result_get()->push_back(*j);
00254                 }
00255         }
00256 }
00257 
00258 void sa_statements::enter_function(ptr< location > loc, ptr<as_function_definition> as_func)
00259 {
00260         DISAMB;
00261         sa_statements_logger << "entering function\n" << msg::eolog;
00262         lassert(as_func);
00263         ptr<ss_function_declaration> ss_func = last_declaration_get().dncast<ss_function_declaration>();
00264         lassert(ss_func);
00265 
00266         // create new compound with all the stuff
00267         ptr<ss_decl_seq> decl_seq = sa_decl_seq_compound_pair_creator::instance()->process(
00268                         loc, // location
00269                         ss_func->parameters_get(), // parent scope (function parameters scope)
00270                         ss_func->parameters_get()->compound_stmt_get() // parent statement
00271                         )->first;
00272         
00273         // fill in a scope declaration
00274         ptr< ss_compound_stmt_declaration > decl = ss_compound_stmt_declaration::create(
00275                         loc,
00276                         ss_declaration_time::infinity(), // visible since
00277                         ss_declaration_time::create(loc->order_get()), // decl time got from location
00278                         ss_dummy_name::create(loc),// ss_name
00279                         ss_func->parameters_get(), // contained in
00280                         ss_void::instance(), // type
00281                         ss_linkage::create("C++",ss_linkage::LINKAGE_NO), // linkage
00282                         decl_seq->compound_stmt_get() // compound stmt
00283                         );
00284         decl_seq->declared_by_set(decl);
00285 
00286         // ss_func is current from now
00287         current_function_set(ss_func);
00288 
00289         // fill in a new context
00290         ptr<sa_as_context> as = sa_as_context::create(
00291                         as_func->declarator_get()->name_get(), // the function name denotes scope
00292                         current_as->access_specifier_get() // access specifier comes from context
00293                         ); // create the as part of the new context
00294         ptr<sa_ss_context> ss = sa_ss_context::create(
00295                         decl_seq,
00296                         current_ss->access_specifier_get()
00297                         ); // create the ss part of the new context
00298         
00299         ptr<sa_context> ctx = sa_context::create(as,ss,current_sa);
00300         sa_context_manager::instance()->push(ctx); // switch to the new context
00301 
00302         ss_func->body_set(current_compound);
00303 
00304         // for each parameter add a fake declaration into the new scope (to avoid redeclaration)
00305         ptr<decl_list> params=ss_func->parameters_get()->contents_get();
00306         for (decl_list::iterator i = params->begin() ; i!=params->end(); i++){
00307                 sa_statements_logger << "creating fake declaration for parameter\n" << msg::eolog;
00308                 insert_fake_declaration(*i);
00309         }
00310 }
00311 
00312 void sa_statements::leave_function()
00313 {
00314         DISAMB;
00315         sa_statements_logger << "leaving function\n" << msg::eolog;
00316         current_function_set(NULL);
00317         sa_context_manager::instance()->pop();
00318 }
00319 
00320 void sa_statements::enter_scope(ptr< location > loc)
00321 {
00322         DISAMB;
00323         if (current_compound->behavior_get() == ss_compound_stmt::NO_CREATE ) {
00324                 current_compound->behavior_set(ss_compound_stmt::NO_LEAVE);
00325                 sa_statements_logger << "not entering scope\n" << msg::eolog;
00326                 return;
00327         }
00328         sa_statements_logger << "entering scope\n" << msg::eolog;
00329         ptr<ss_decl_seq> decl_seq = sa_decl_seq_compound_pair_creator::instance()->process(
00330                         loc, // location
00331                         current_decl_seq, // parent scope
00332                         current_compound // parent statement
00333                         )->first; // create new compound with all the stuff
00334 
00335         ptr< ss_compound_stmt_declaration > decl = ss_compound_stmt_declaration::create(
00336                         loc,
00337                         ss_declaration_time::infinity(), // visible since
00338                         ss_declaration_time::create(loc->order_get()), // decl time got from location
00339                         ss_dummy_name::create(loc),// ss_name
00340                         current_decl_seq, // contained in
00341                         ss_void::instance(), // type
00342                         ss_linkage::create("C++",ss_linkage::LINKAGE_NO), // linkage
00343                         decl_seq->compound_stmt_get() // compound stmt
00344                         );
00345         decl_seq->declared_by_set(decl); // fill in a scope declaration (dummy)
00346 
00347         // add the new compound statement into current scope
00348         current_statements->push_back(decl_seq->compound_stmt_get());
00349 
00350         // connect sequence points
00351         ptr<ss_sp> alpha = current_psp;
00352         ptr<ss_sp> beta = current_nsp;
00353         ptr<ss_sp> gamma = decl_seq->compound_stmt_get()->psp_get();
00354         ptr<ss_sp> delta = decl_seq->compound_stmt_get()->nsp_get();
00355         alpha->nsp_set(gamma);
00356         gamma->psp_set(alpha);
00357         delta->nsp_set(beta);
00358         beta->psp_set(delta);
00359         
00360         ptr<sa_as_context> as = sa_as_context::create(
00361                         as_name::create(loc,NULL,as_empty_id::create(loc)), // FIXME? is dummy name all right?
00362                         current_as->access_specifier_get()
00363                         ); // create the as part of the new context
00364         ptr<sa_ss_context> ss = sa_ss_context::create(
00365                         decl_seq,
00366                         current_ss->access_specifier_get()
00367                         ); // create the ss part of the new context
00368         
00369         ptr<sa_context> ctx = sa_context::create(as,ss,current_sa);
00370         sa_context_manager::instance()->push(ctx); // push the new context on context stack
00371 }
00372 
00373 void sa_statements::leave_scope()
00374 {
00375         DISAMB;
00376         if (current_compound->behavior_get() == ss_compound_stmt::NO_LEAVE ) {
00377                 current_compound->behavior_set(ss_compound_stmt::NORMAL);
00378                 sa_statements_logger << "not leaving scope\n" << msg::eolog;
00379                 return;
00380         }
00381         sa_statements_logger << "leaving scope\n" << msg::eolog;
00382         sa_context_manager::instance()->pop();
00383 }
00384 
00385 void sa_statements::insert_fake_declaration(ptr<ss_declaration> input_decl)
00386 {
00387         ptr<ss_declaration> decl = get_real_declaration::instance()->process(input_decl);
00388         // fake is a copy of the original declaration
00389         ptr<ss_fake_declaration> fake = ss_fake_declaration::create(
00390                         decl->location_get(),
00391                         decl->visible_since_get(),
00392                         decl->decl_time_get(),
00393                         decl->name_get(),
00394                         decl->contained_in_get(),
00395                         decl->type_get(),
00396                         decl->linkage_get(),
00397                         decl.dncast<ss_object_declaration>()
00398                         );
00399         current_decl_seq->contents_get()->push_back(fake);
00400 }
00401 
00402 void sa_statements::expression_stmt(ptr< ::lestes::lang::cplus::sem::as_expression> as )
00403 {
00404         DISAMB;
00405         sa_statements_logger << "inserting expression statement\n" << msg::eolog;
00406         lassert(current_function);
00407         
00408         ALPHABETASPS(as->location_get());
00409 
00410         // visitor gives me ss_expression
00411         ptr<ss_expression> expr = sa_expression_converter::create(alpha,beta,sps)->process(as);
00412         if (!expr) return; // empty expression -> the statement is discarded
00413 
00414         // create the resulting SS statement
00415         ptr<ss_expr_stmt> stmt = ss_expr_stmt::create(
00416                 as->location_get(), // location
00417                 label_list::create(), // labels pointing at me
00418                 current_compound, // parent scope
00419                 alpha, // psp
00420                 beta, // nsp
00421                 sps, // list of sp in this statement
00422                 expr // transformed expression
00423         );
00424         
00425         // append the SS statement into resulting scope
00426         current_statements->push_back(stmt);
00427 }
00428 
00429 void sa_statements::return_stmt(ptr< ::lestes::lang::cplus::sem::as_return_statement > as )
00430 {
00431         DISAMB;
00432         sa_statements_logger << "inserting return statement\n" << msg::eolog;
00433         lassert(current_function);
00434         
00435         ALPHABETASPS(as->location_get());
00436 
00437         // resolve return type of current function
00438         ptr<ss_type> type = current_function->type_get().dncast<ss_function>()->returns_get();
00439         
00440         // visitor gives me ss_expression of that type
00441         ptr<ss_expression> expr = sa_expression_converter::create(alpha,beta,sps,type,NULL)->process(as->value_get());
00442         
00443         // create the resulting SS statement
00444         ptr<ss_return> stmt = ss_return::create(
00445                 as->location_get(), // location
00446                 label_list::create(), // labels pointing at me
00447                 current_compound, // parent scope
00448                 alpha, // psp
00449                 beta, // nsp
00450                 sps, // list of sp in this statement
00451                 expr // transformed expression
00452         );
00453         
00454         // append the SS statement into resulting scope
00455         current_statements->push_back(stmt);
00456 }
00457 
00458 void sa_expression_converter::convert(ptr<as_expression> as)
00459 {
00460         sa_statements_logger << "converting AS expression to SS\n" << msg::eolog;
00461         lassert(as);
00462         // transform the AS expression to functional
00463         ptr<or_or_functional> functional = sa_deconstruct_spse::create()->process(as);
00464 
00465         // transform the functional to SS expression
00466         ptr<ss_expression> expr = (*functional)(alpha,beta,as->location_get(),sps);     
00467 
00468         if (type) {
00469                 sa_statements_logger << "type conversion\n" << msg::eolog;
00470 
00471                 // resolve the conversion sequence
00472                 ptr<or_ics_functional> ics = or_find_ics(functional,type);
00473                 if (!ics){
00474                         report << conversion_not_found << as->location_get() ;
00475                         exit(1);
00476                 }
00477 
00478                 // proceed the conversion sequence
00479                 expr = (*ics)(expr, expr->psp_get(), expr->nsp_get());
00480         }
00481         
00482         result = expr;
00483 }
00484 
00485 void sa_expression_converter::visit_as_empty_expression(ptr<as_empty_expression> as)
00486 {
00487         sa_statements_logger << "empty expression\n" << msg::eolog;
00488         lassert(as);
00489         result = NULL;
00490 }
00491 
00492 ptr<ss_compound_stmt> sa_statements::new_compound(ptr<location> loc)
00493 {
00494         ptr<ss_compound_stmt> stmt = sa_decl_seq_compound_pair_creator::instance()->process(
00495                         loc, // location
00496                         current_decl_seq, // parent scope
00497                         current_compound // parent statement
00498                         )->second; // create new compound with all the stuff
00499 
00500         ptr< ss_compound_stmt_declaration > decl = ss_compound_stmt_declaration::create(
00501                         loc,
00502                         ss_declaration_time::infinity(), // visible since
00503                         ss_declaration_time::create(loc->order_get()), // decl time got from location
00504                         ss_dummy_name::create(loc),// ss_name
00505                         current_decl_seq, // contained in
00506                         ss_void::instance(), // type
00507                         ss_linkage::create("C++",ss_linkage::LINKAGE_NO), // linkage
00508                         stmt // compound stmt
00509                         );
00510         stmt->decl_seq_get()->declared_by_set(decl); // fill in a scope declaration (dummy)
00511         return stmt;
00512 }
00513 
00514 void sa_statements::if_head(ptr<location> loc, ptr<as_condition> cond)
00515 {
00516         DISAMB;
00517         sa_statements_logger << "if head\n" << msg::eolog;
00518         lassert(loc);
00519         lassert(cond);
00520         ALPHABETASPS(loc);
00521         ptr<ss_expression> expr = condition_to_expression::create(alpha,beta,sps)->process(cond);
00522 
00523         /*! FIXME
00524                 Location of the 'then' and 'else' compound statements is set to the 'if' token location.
00525                 It would be difficult to set it properly because the statements must be created earlier
00526                 than the parser reaches them. Who cares, anyway...
00527          */
00528         ptr<ss_compound_stmt> cthen = new_compound(loc);
00529         cthen->behavior_set(ss_compound_stmt::NO_CREATE);
00530         ptr<ss_compound_stmt> celse = new_compound(loc);
00531         celse->behavior_set(ss_compound_stmt::NO_CREATE);
00532         // connect sequence points
00533         beta->nsp_set(cthen->psp_get());
00534         cthen->psp_get()->psp_set(beta);
00535         cthen->nsp_get()->nsp_set(celse->psp_get());
00536         celse->psp_get()->psp_set(cthen->nsp_get());
00537         celse->nsp_get()->nsp_set(current_nsp);
00538         current_nsp->psp_set(celse->nsp_get());
00539         
00540         ptr<ss_if_stmt> stmt = ss_if_stmt::create(
00541                         loc, // location
00542                         label_list::create(), // labels pointing at me
00543                         current_compound, // parent
00544                         alpha, // psp
00545                         beta, // nsp
00546                         sps, // list of SP
00547                         expr, // condition
00548                         cthen, // cthen
00549                         celse // celse
00550                         );
00551         current_statements->push_back(stmt);
00552         sa_statements_logger << "inserting if statement\n" << msg::eolog;
00553         current_statements->push_back(cthen);
00554         sa_statements_logger << "inserting then compound\n" << msg::eolog;
00555         current_statements->push_back(celse);
00556         sa_statements_logger << "inserting else compound\n" << msg::eolog;
00557         
00558         enter_subcompound(cthen);
00559 }
00560 
00561 void sa_statements::while_head(ptr<location> loc, ptr<as_condition> cond)
00562 {
00563         DISAMB;
00564         sa_statements_logger << "while head\n" << msg::eolog;
00565         lassert(loc);
00566         lassert(cond);
00567         ALPHABETASPS(loc);
00568         ptr<ss_expression> expr = condition_to_expression::create(alpha,beta,sps)->process(cond);
00569 
00570         /*! FIXME
00571                 The location is not quite correct. See if statement.
00572          */
00573         ptr<ss_compound_stmt> body = new_compound(loc);
00574         body->behavior_set(ss_compound_stmt::NO_CREATE);
00575         // connect sequence points
00576         beta->nsp_set(body->psp_get());
00577         body->psp_get()->psp_set(beta);
00578         
00579         ptr<ss_while> stmt = ss_while::create(
00580                         loc, // location
00581                         label_list::create(), // labels pointing at me
00582                         current_compound, // parent
00583                         alpha, // psp
00584                         beta, // nsp
00585                         sps, // list of SP
00586                         body, // body
00587                         expr // condition
00588                         );
00589         current_statements->push_back(stmt);
00590         sa_statements_logger << "inserting while statement\n" << msg::eolog;
00591         current_statements->push_back(body);
00592         sa_statements_logger << "inserting while body compound\n" << msg::eolog;
00593         
00594         enter_subcompound(body);
00595 }
00596 
00597 void sa_statements::for_head(ptr<source_location> loc, ptr<as_condition> cond, ptr<as_expression> iter)
00598 {
00599         DISAMB;
00600         sa_statements_logger << "for head\n" << msg::eolog;
00601         lassert(loc);
00602         lassert(cond);
00603         ALPHABETASPS(loc);
00604         ptr<ss_expression> expr = condition_to_expression::create(alpha,beta,sps)->process(cond);
00605 
00606         ptr<ss_sp> iter_alpha = ss_sp::create(iter->location_get(), NULL, NULL, 0);
00607         ptr<ss_sp> iter_beta = ss_sp::create(iter->location_get(), NULL, NULL, 0);
00608         ptr<sp_list> iter_sps = sp_list::create();
00609         iter_sps->push_back(iter_alpha);
00610         iter_sps->push_back(iter_beta);
00611         ptr<ss_expression> iter_expr = sa_expression_converter::create(iter_alpha,iter_beta,iter_sps)->process(iter);
00612         ptr<ss_expr_stmt> iter_stmt;
00613         if (iter_expr) iter_stmt= ss_expr_stmt::create(
00614                         iter->location_get(), // location
00615                         label_list::create(), // labels pointing at me
00616                         current_compound, // parent
00617                         iter_alpha,
00618                         iter_beta,
00619                         iter_sps,
00620                         iter_expr
00621                         );
00622         
00623         /*! FIXME
00624                 The location is not correct. See if statement.
00625          */
00626         ptr<ss_compound_stmt> body = new_compound(loc);
00627         body->behavior_set(ss_compound_stmt::NO_CREATE);
00628         // connect sequence points
00629         beta->nsp_set(body->psp_get());
00630         body->psp_get()->psp_set(beta);
00631         
00632         ptr<ss_for> stmt = ss_for::create(
00633                         loc, // location
00634                         label_list::create(), // labels pointing at me
00635                         current_compound, // parent
00636                         alpha, // psp
00637                         beta, // nsp
00638                         sps, // list of SP
00639                         body, // body
00640                         expr, // condition
00641                         iter_stmt // iteration
00642                         );
00643 
00644         // connect sequence points of the iteration statement { {for(;;iter_stmt){..} __here__ } }
00645         if (iter_stmt) {
00646                 iter_stmt->psp_get()->psp_set(stmt->nsp_get());
00647                 stmt->nsp_get()->nsp_set(iter_stmt->psp_get());
00648                 iter_stmt->nsp_get()->nsp_set(current_compound->destructor_sp_get());
00649                 current_compound->destructor_sp_get()->psp_set(iter_stmt->nsp_get());
00650         }
00651         
00652         sa_statements_logger << "inserting for statement\n" << msg::eolog;
00653         current_statements->push_back(stmt);
00654         sa_statements_logger << "inserting for body compound\n" << msg::eolog;
00655         current_statements->push_back(body);
00656         current_statements->push_back(iter_stmt);
00657 
00658         enter_subcompound(body);
00659 }
00660 
00661 void sa_statements::for_inner_action(ptr<source_location> loc)
00662 {
00663         DISAMB;
00664         lassert(loc);
00665         sa_statements_logger << "entering 'for' inner compound\n" << msg::eolog;
00666         ptr<ss_compound_stmt> inner = new_compound(loc);
00667         current_statements->push_back(inner);
00668         enter_subcompound(inner);
00669 }
00670 
00671 void condition_to_expression::visit_as_empty_condition(ptr<as_empty_condition> cond)
00672 {
00673         lassert(cond);
00674         sa_statements_logger << "condition - empty\n" << msg::eolog;
00675         // Missing condition.
00676         // In for-cycle it's ok and the 'true' expression is created.
00677         // Otherwise the error was already reported by parser and this is recovery.
00678         result = ss_literal::create(cond->location_get(),ss_bool::instance(),psp,nsp,
00679                                 ss_integral_literal_info::create_from_number(ss_bool::instance(),1));
00680 }
00681 
00682 void condition_to_expression::visit_as_condition_expression(ptr<as_condition_expression> cond)
00683 {
00684         lassert(cond);
00685         sa_statements_logger << "condition - expression\n" << msg::eolog;
00686         result = sa_expression_converter::create(psp,nsp,sps,ss_bool::instance(),NULL)->process(cond->expression_get());
00687 }
00688 
00689 void condition_to_expression::visit_as_condition_declaration(ptr<as_condition_declaration> cond)
00690 {
00691         lassert(cond);
00692         sa_statements_logger << "condition - declaration\n" << msg::eolog;
00693         // declaration of the variable is the last in current scope
00694         ptr<ss_declaration> decl = current_decl_seq->contents_get()->back();
00695         // create a functional (needed for conversion purposes)
00696         ptr<or_or_functional_decl> functional = or_or_functional_decl::create(
00697                         ss_pseudoreference::instance(decl->type_get()),
00698                         decl
00699                         );
00700         // transform the functional to SS expression
00701         ptr<ss_expression> expr = (*functional)(psp,nsp,cond->location_get(),sps);
00702         sa_statements_logger << "type conversion to bool\n" << msg::eolog;
00703         // resolve the conversion sequence
00704         ptr<or_ics_functional> ics = or_find_ics(functional,ss_bool::instance());
00705         if (!ics){
00706                 report << conversion_not_found << cond->location_get() ;
00707                 exit(1);
00708         }
00709         // proceed the conversion sequence
00710         expr = (*ics)(expr, expr->psp_get(), expr->nsp_get());
00711 
00712         result = expr;
00713 }
00714 
00715 void sa_statements::condition_decl(ptr<location> loc, ptr<as_expression> inizer)
00716 {
00717         lassert(loc);
00718         lassert(inizer);
00719         lassert2(last_declaration,"declarator without declaration?");
00720         sa_statements_logger << "creating declaration statement from condition\n" << msg::eolog;
00721         ALPHABETASPS(loc);
00722         ptr<ss_expression> expr = sa_expression_converter::create(alpha,beta,sps)->process(inizer);
00723         ptr<expr_list> exprs = expr_list::create();
00724         exprs->push_back(expr);
00725 
00726         ptr<ss_decl_stmt> stmt = ss_decl_stmt::create(
00727                         loc, // location
00728                         label_list::create(), // labels pointing at me
00729                         current_compound, // parent
00730                         alpha, // psp
00731                         beta, // nsp
00732                         sps, // list of SP
00733                         last_declaration_get(), // declaration
00734                         exprs, // args
00735                         ss_decl_stmt::IK_COPY_INITIALIZATION // initializer kind
00736                         );
00737         current_statements->push_back(stmt);
00738 }
00739 
00740 void sa_statements::enter_subcompound(ptr<ss_compound_stmt> scope)
00741 {
00742         lassert(scope);
00743         sa_statements_logger << "entering subcompound\n" << msg::eolog;
00744         
00745         // remember the declarations, if there are some
00746         ptr<decl_list> decls = scope->parent_get()->decl_seq_get()->contents_get();
00747 
00748         // switch context to the given scope
00749         ptr<sa_as_context> as = sa_as_context::create(
00750                         as_name::create(
00751                                 scope->location_get(),
00752                                 NULL,
00753                                 as_empty_id::create(scope->location_get())
00754                                 ), // FIXME? is dummy name all right?
00755                         current_as->access_specifier_get()
00756                         ); // create the as part of the new context
00757         ptr<sa_ss_context> ss = sa_ss_context::create(
00758                         scope->decl_seq_get(),
00759                         current_ss->access_specifier_get()
00760                         ); // create the ss part of the new context
00761         ptr<sa_context> ctx = sa_context::create(as,ss,current_sa);
00762         sa_context_manager::instance()->push(ctx); // push the new context on context stack
00763 
00764         for( decl_list::iterator i = decls->begin(); i!=decls->end(); i++ ) {
00765                         sa_statements_logger << "creating fake declaration\n" << msg::eolog;
00766                         // fake is a copy of the original declaration
00767                         insert_fake_declaration(*i);
00768         }
00769 }
00770 
00771 void sa_statements::enter_else()
00772 {
00773         DISAMB;
00774         enter_subcompound(
00775                 sa_context_manager::instance()->current()->ss_get()->scope_get()
00776                         ->compound_stmt_get()->statements_get()->back().dncast<ss_compound_stmt>()
00777         );
00778 }
00779 
00780 void get_real_declaration::visit_ss_fake_declaration(ptr<ss_fake_declaration> fake)
00781 {
00782         lassert(fake);
00783         result = fake->real_decl_get();
00784 }
00785 
00786 void get_real_declaration::default_action(ptr<ss_declaration> decl)
00787 {
00788         lassert(decl);
00789         result = decl;
00790 }
00791 
00792 /* NOTE:
00793                 as->identifier_get()->token_get()->wrapped_token_get()->value_get(), // ucn_string extracted from bison token
00794 */
00795 
00796 
00797 end_package(sem);
00798 end_package(cplus);
00799 end_package(lang);
00800 end_package(lestes);
00801 

Generated on Mon Feb 12 18:23:14 2007 for lestes by doxygen 1.5.1-20070107