00001
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
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
00047
00048
00049 bool
00050 Translate_visitor::visit_function(Ptree* storagespec,
00051 Ptree* returntype,
00052 PtreeDeclarator* decl,
00053 PtreeBlock* block)
00054 {
00055
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
00077
00078 _var[name].type = string("C'T") + enctype;
00079 _var[name].alloc = "text";
00080
00081 _func = name;
00082
00083
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());
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
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
00145
00146 string initializer;
00147
00148
00149
00150
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 }
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
00194
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
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
00231
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
00252
00253
00254
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
00282
00283
00284
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
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());
00345
00346 string name (exp->ToString());
00347
00348
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)
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
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
00389 assert (exp->IsLeaf());
00390
00391 string leaf (exp->ToString());
00392
00393
00394 if (leaf == "true")
00395 new_value ("True");
00396 else if (leaf == "false")
00397 new_value ("False");
00398
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
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
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
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
00457 new_state (Sstring () << "if_alloc state "
00458 << _var[name].name << "_vrec");
00459
00460
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
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
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 }