Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

translator.cc

Go to the documentation of this file.
00001 // AUTOMATICALLY GENERATED -- DO NOT EDIT!         -*- c++ -*-
00002 
00003 #include "translator.h"
00004 #include "translator_i.h"
00005 
00006 #line 27 "translator.cpp"
00007 
00008 using namespace std;
00009 
00010 #line 29 "translator.cpp"
00011 
00012 void
00013 Translator::translate(Source* s)
00014 {
00015   Translate_visitor translator (s);
00016 
00017   translator.visit ();
00018 }
00019 
00020 #line 69 "translator.cpp"
00021 
00022 
00023 Translate_visitor::Translate_visitor(Source* s)
00024   : Ptree_program_visitor<bool> (s), 
00025     Ptree_visitor<bool> (s), 
00026     _value (-1),
00027     _number (0),
00028     _alloc ("static"),
00029     _last_alloc (""),
00030     _expecting_lvalue (false),
00031     //    _have_initializer (false),
00032     out (&cout)
00033 {
00034 }
00035 
00036 #line 83 "translator.cpp"
00037 
00038 
00039 Translate_visitor::~Translate_visitor()
00040 {
00041 }
00042 
00043 #line 88 "translator.cpp"
00044 
00045 // 
00046 // From here on, override functions of Ptree_visitor to translate the program.
00047 // 
00048 
00049 bool
00050 Translate_visitor::visit_function(Ptree* storagespec, 
00051                                    Ptree* returntype, 
00052                                    PtreeDeclarator* decl, 
00053                                    PtreeBlock* block)
00054 {
00055   // Only handle built-in types for now
00056 
00057   char *enctype = returntype->Car()->ToString();
00058   char *encname = decl->Car()->ToString();
00059 
00060   if (!encname || !enctype) 
00061     {
00062       throw "encname or enctype null";
00063     }
00064 
00065   cerr << "name = " << encname << "; type = " << enctype << endl;
00066 
00067   Ptree& name_node = decl->IsLeaf() ? *decl : *decl->First();
00068 
00069   string name = _sym.insert (name_node, 'F');
00070 
00071   _var[name].name = name;
00072   _var[name].basename = name_node.ToString();
00073   _var[name].enctype = enctype;
00074   _var[name].number = _number++;
00075 
00076   // Record the function here.  Rest of precessing done later
00077   // in TranslateFunctionBody.
00078   _var[name].type = string("C'T") + enctype;
00079   _var[name].alloc = "text";
00080 
00081   _func = name;
00082 
00083   // XXX handle arguments
00084 
00085   _sym.enter_scope(_var[_func].basename, 'F');
00086 
00087   string type = _var[_func].type == "C'Tvoid" ? "" : _var[_func].type;
00088 
00089   new_function_prologue (_func, type);
00090 
00091   string old_alloc = _alloc;
00092   _alloc = "stack";
00093   _last_alloc = "";
00094 
00095   assert (* block->First()->ToString() = '{');
00096   assert (* block->Third()->ToString() = '}');
00097   visit (block->Second());      // Skip block's braces
00098 
00099   new_function_epilogue (_func, type == "" ? "" : "retvalue");
00100 
00101   _alloc = old_alloc;
00102   _sym.leave_scope();
00103 
00104   _func = "";
00105   return true;
00106 }
00107 
00108 #line 151 "translator.cpp"
00109 
00110 bool 
00111 Translate_visitor::visit_name_declaration(Ptree* storagespec, 
00112                                            Ptree* type, 
00113                                            Ptree* decllist)
00114 {
00115   for (;
00116        decllist;
00117        decllist = decllist->Cdr() ? decllist->Cdr()->Cdr() : 0)
00118     {
00119       Ptree* decl = decllist->Car();
00120 
00121       // Only handle built-in types for now
00122       char *enctype = type->Car()->ToString();
00123       char *encname = decl->First()->ToString();
00124       
00125       if (!encname || !enctype) 
00126         {
00127           throw "encname or enctype null";
00128         }
00129       
00130       cerr << "name = " << encname << "; type = " << enctype << endl;
00131       
00132       Ptree* name_node = decl->First();
00133       
00134       string name = _sym.insert (*name_node, 'V');
00135       
00136       _var[name].name = name;
00137       _var[name].basename = name_node->ToString();
00138       _var[name].enctype = enctype;
00139       _var[name].number = _number++;
00140 
00141       _var[name].type = string("C'T") + enctype;
00142       _var[name].alloc = _alloc;
00143       
00144       // Now visit initializers, if any.
00145       
00146       string initializer;       // Default: no initialization
00147       
00148       // TODO: lookup = operator or constructor
00149       
00150       // Find expression
00151       Ptree* exp;
00152       
00153       for (exp = decl->Cdr(); exp; exp = exp->Cdr())
00154         {
00155           if (exp->Car()->IsLeaf() && * exp->Car()->ToString() == '=')
00156             {
00157               break;
00158             }
00159         }
00160       
00161       if (exp)
00162         {
00163           exp = exp->Cdr();
00164           
00165           ostream* old_out = out;
00166           out = &_expr;
00167           _expr.str("");
00168           
00169           visit (exp);
00170           
00171           cerr << "Found an initializer: " << _expr.str() << endl;
00172           
00173           out = old_out;
00174           
00175           initializer = _expr.str();
00176         }
00177       
00178       new_variable (name, initializer);
00179     } // for
00180 
00181   return true;
00182 }
00183 
00184 #line 225 "translator.cpp"
00185 
00186 bool
00187 Translate_visitor::visit_return(PtreeReturnStatement* exp)
00188 {
00189   if (_var[_func].type == "C'Tvoid")
00190     {
00191       if (exp->Length() != 2)
00192         {
00193           // XXX actually, void functions _can_ return a value if that
00194           // value is cast to void.
00195           throw "void functions cannot return a value"; 
00196         }
00197 
00198       return exp;
00199     }
00200 
00201   if (_var[_func].type != "C'Tvoid"
00202       && exp->Length() == 2)
00203     {
00204       throw "Non-void function must return a value";
00205     }
00206 
00207   visit (exp->Second());
00208 
00209   *out << "let retvalue = value_" << _value << endl;
00210 
00211   return true;
00212 }
00213 
00214 #line 253 "translator.cpp"
00215 
00216 
00217 bool
00218 Translate_visitor::visit_exprstatement(PtreeExprStatement* exp)
00219 {
00220   // Skip over final ';'
00221   assert (* exp->Second()->ToString() = ';');
00222   return visit (exp->First());
00223 }
00224 
00225 #line 262 "translator.cpp"
00226 
00227 bool
00228 Translate_visitor::visit_assign(PtreeAssignExpr* exp)
00229 {
00230   // [left = right]
00231   // TODO: lookup = operator
00232 
00233   visit(exp->Third());
00234 
00235   _expecting_lvalue = true;
00236 
00237   visit(exp->First());
00238 
00239   if (_expecting_lvalue)
00240     throw string ("Cannot assign to expression \"") + exp->First()->ToString()
00241       + "\"";
00242 
00243   return true;
00244 }
00245 
00246 #line 281 "translator.cpp"
00247 
00248 bool
00249 Translate_visitor::visit_infix(PtreeInfixExpr* exp)
00250 {
00251   // [left operator right]
00252   // TODO: lookup operator
00253   
00254   // XXX Fixed evaluation order: Right to left
00255 
00256   push_lvalue();
00257 
00258   string op (exp->Second()->ToString());
00259 
00260   cerr << "Translating infix expression " << op << endl;
00261 
00262   visit (exp->Third());
00263   int right = _value;
00264 
00265   visit (exp->First());
00266   int left = _value;
00267 
00268   new_value (Sstring() << "value_" << left << " "
00269              << op << " value_" << right);
00270 
00271   pop_lvalue();
00272 
00273   return true;
00274 }
00275 
00276 #line 309 "translator.cpp"
00277 
00278 bool
00279 Translate_visitor::visit_postfix(PtreePostfixExpr* exp)
00280 {
00281   // [expr operator++/--]
00282   // TODO: lookup operator
00283 
00284   // XXX Fixed evaluation order: Update occurs right after evaluation
00285 
00286   push_lvalue();
00287   
00288   string op (exp->Second()->ToString());
00289   assert (op == "++" || op == "--");
00290 
00291   cerr << "Translating postfix expression " << op << endl;
00292 
00293   visit (exp->First());
00294   int result = _value;
00295 
00296   new_value (Sstring () << "value_" << result << " "
00297              << (op == "++" ? "+" : "-") << " 1");
00298 
00299   _expecting_lvalue = true;
00300 
00301   visit (exp->First());
00302 
00303   if (_expecting_lvalue)
00304     throw string ("Cannot assign to ") + exp->First()->ToString();
00305 
00306   new_value (Sstring() << "value_" << result);
00307 
00308   pop_lvalue();
00309 
00310   return true;
00311 }
00312 
00313 #line 344 "translator.cpp"
00314 
00315 bool
00316 Translate_visitor::visit_funcall(PtreeFuncallExpr* exp)
00317 {
00318   string global;
00319   _sym.lookup_global_name (*exp->Car(), &global);
00320 
00321   // XXX find arguments in exp->Crd()
00322 
00323   if (_var[global].type == "C'Tvoid")
00324     new_state (global);
00325   else
00326     {
00327       *out << "let (state, retval) = " << global << " in" << endl;
00328       
00329       new_value ("retval");
00330       new_state ("state");
00331     }
00332 
00333   return true;
00334 }
00335 
00336 #line 365 "translator.cpp"
00337 
00341 bool
00342 Translate_visitor::visit_name(Ptree* exp)
00343 {
00344   assert (exp->IsLeaf());       // Handle only unscoped names for now.
00345   
00346   string name (exp->ToString());
00347   
00348   // First check for keywords.  Parse them like constants.
00349   if (name == "true" || name == "false")
00350     return visit_leaf (dynamic_cast<Leaf*>(exp));
00351 
00352   string global;
00353   if (! _sym.lookup_global_name (*exp, &global))
00354     throw "Unknown variable";
00355 
00356   vrec* var = &_var[global];
00357   
00358   if (var->alloc != _last_alloc)
00359     {
00360       new_state (Sstring() << "if_change_alloc state " << var->alloc);
00361       _last_alloc = var->alloc;
00362     }
00363 
00364   if (_expecting_lvalue)        // Variable write
00365     {
00366       cerr << "Writing to variable " << var->name << endl;
00367 
00368       new_state (Sstring() << "if_write state " << var->name << "_vrec "
00369                  << "value_" << _value);
00370 
00371       _expecting_lvalue = false;
00372     }
00373   else                          // Variable read
00374     {
00375       cerr << "Reading from variable " << var->name << endl; 
00376 
00377       new_value (Sstring() << "if_read state " << var->name << "_vrec");
00378     }
00379 
00380   return true;
00381 }
00382 
00383 #line 410 "translator.cpp"
00384 
00385 bool
00386 Translate_visitor::visit_leaf(Leaf* exp)
00387 {
00388   // Translate expression -- hopefully a constant
00389   assert (exp->IsLeaf());
00390 
00391   string leaf (exp->ToString());
00392   
00393   // First check for keywords.  Parse them like constants.
00394   if (leaf == "true")
00395     new_value ("True");
00396   else if (leaf == "false")
00397     new_value ("False");
00398   // Numerics?
00399   else if (leaf.find_first_not_of ("0123456789") == string::npos)
00400     new_value (string("#") + leaf);
00401   else
00402     throw "Unknown stuff -- barf!";
00403 
00404   return true;
00405 }
00406 
00407 #line 432 "translator.cpp"
00408 
00409 // 
00410 // Output functions
00411 // 
00412 void 
00413 Translate_visitor::new_value(const string& val)
00414 {
00415   *out << "let value_" << ++_value << " = " << val << " in" << endl;
00416 }
00417 
00418 #line 441 "translator.cpp"
00419 
00420 void
00421 Translate_visitor::new_variable(const string& name,
00422                                 const string& initializer)
00423 {
00424   cerr << "  Allocating number " << _var[name].number 
00425        << " for variable " 
00426        << _var[name].name << " from allocator " 
00427        << _var[name].alloc << endl;
00428 
00429   // Declare a vrec for this variable
00430   if (_var[name].alloc == "stack") 
00431     *out << "let " << _var[name].name << "_vrec = ";
00432   else 
00433     *out << "constdefs " << name << "_vrec :: \"" 
00434          << _var[name].type << " VREC\"" << endl
00435          << "          \"" << name << "_vrec == ";
00436 
00437   *out << "(| vr_locn = #" << _var[name].number 
00438        << ", vr_type = dummy_" << _var[name].type << " |)";
00439 
00440   if (_var[name].alloc == "stack") 
00441     *out << " in" << endl;
00442   else
00443     {
00444       *out << "\"" << endl << endl;
00445 
00446       new_function_prologue (name + "_alloc", "");
00447     }
00448 
00449   // Switch to current allocator
00450   if (_var[name].alloc != _last_alloc)
00451     {
00452       new_state (Sstring () << "if_change_alloc state " << _var[name].alloc);
00453       _last_alloc = _var[name].alloc;
00454     }
00455   
00456   // Allocate this variable from the current allocator
00457   new_state (Sstring () << "if_alloc state " 
00458              << _var[name].name << "_vrec");
00459   
00460   // Initialize the variable.
00461   if (initializer != "")
00462     {
00463       *out << initializer;
00464       new_state (Sstring() << _var[name].type << "'directinit state "
00465                  << _var[name].name << "_vrec value_" << _value);
00466     }
00467   else
00468     new_state (Sstring() << _var[name].type << "'defaultinit state "
00469                << _var[name].name << "_vrec");
00470 
00471   if (_var[name].alloc == "stack") 
00472     // Get new allocator state
00473     *out << "let " << _var[name].alloc << " = (snd state) in" << endl;
00474   else
00475     new_function_epilogue (name + "_alloc", "");
00476 
00477 }
00478 
00479 #line 500 "translator.cpp"
00480 
00481 void
00482 Translate_visitor::new_function_prologue(const string& name, 
00483                                          const string& rettype)
00484 {
00485   *out << "constdefs " << name << " :: \"State => ";
00486 
00487   if (rettype != "")
00488     *out << "(State * " << rettype << ")";
00489   else
00490     *out << "State";
00491 
00492   *out << " option\"" << endl
00493        << "\"" << name << " state ==" << endl;
00494 }
00495 
00496 #line 515 "translator.cpp"
00497 
00498 void
00499 Translate_visitor::new_function_epilogue(const string& name, 
00500                                          const string& value)
00501 {
00502   if (value != "")
00503     *out << "Some (state * " << value << ")\"" << endl << endl;
00504   else
00505     *out << "Some state" << "\"" << endl << endl;
00506   
00507 }
00508 
00509 #line 526 "translator.cpp"
00510 
00511 void 
00512 Translate_visitor::new_state(const string& func)
00513 {
00514   *out << "let state = " << func << " in" << endl;
00515 }
00516 
00517 #line 532 "translator.cpp"
00518 
00519 // 
00520 // Helper functions to keep track of lvalue evaluations
00521 // 
00522 void
00523 Translate_visitor::push_lvalue()
00524 {
00525   _lvalue_stack.push (_expecting_lvalue);
00526   _expecting_lvalue = false;
00527 }
00528 
00529 #line 542 "translator.cpp"
00530 
00531 void
00532 Translate_visitor::pop_lvalue()
00533 {
00534   _expecting_lvalue = _lvalue_stack.top ();
00535   _lvalue_stack.pop();
00536 }

Generated on Mon Feb 10 17:32:58 2003 for VFiasco Semantics Compiler by doxygen1.2.15