diff options
| author | Li Jin <dragon-fly@qq.com> | 2017-07-19 15:26:04 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2017-07-19 15:26:04 +0800 |
| commit | 3b270690501cfcc9220c8d5b63ab6f13fc2bd6b0 (patch) | |
| tree | 0f3c76f1318269b8d70d646794b3424be145dd2d /MoonParser/moon_ast.cpp | |
| parent | 65dd230959dbab99b52b99fd807534c254fb4ed9 (diff) | |
| download | yuescript-3b270690501cfcc9220c8d5b63ab6f13fc2bd6b0.tar.gz yuescript-3b270690501cfcc9220c8d5b63ab6f13fc2bd6b0.tar.bz2 yuescript-3b270690501cfcc9220c8d5b63ab6f13fc2bd6b0.zip | |
stop implementing moon compiler.
Diffstat (limited to 'MoonParser/moon_ast.cpp')
| -rw-r--r-- | MoonParser/moon_ast.cpp | 393 |
1 files changed, 3 insertions, 390 deletions
diff --git a/MoonParser/moon_ast.cpp b/MoonParser/moon_ast.cpp index 41d0c55..d8a0db9 100644 --- a/MoonParser/moon_ast.cpp +++ b/MoonParser/moon_ast.cpp | |||
| @@ -7,125 +7,6 @@ | |||
| 7 | #include <vector> | 7 | #include <vector> |
| 8 | #include "moon_ast.h" | 8 | #include "moon_ast.h" |
| 9 | 9 | ||
| 10 | class Data | ||
| 11 | { | ||
| 12 | public: | ||
| 13 | Data() | ||
| 14 | { | ||
| 15 | indent = 0; | ||
| 16 | callerStack.push(false); | ||
| 17 | } | ||
| 18 | |||
| 19 | Converter conv; | ||
| 20 | std::stringstream temp; | ||
| 21 | std::stringstream buffer; | ||
| 22 | std::vector<int> lineTable; | ||
| 23 | std::stack<bool> callerStack; | ||
| 24 | std::stack<std::string> withStack; | ||
| 25 | |||
| 26 | void beginLine(int line = -1) | ||
| 27 | { | ||
| 28 | for (int i = 0; i < indent; i++) | ||
| 29 | { | ||
| 30 | buffer << '\t'; | ||
| 31 | } | ||
| 32 | lineTable.push_back(line == -1 ? lineTable.back() : line); | ||
| 33 | } | ||
| 34 | |||
| 35 | void endLine() | ||
| 36 | { | ||
| 37 | buffer << '\n'; | ||
| 38 | } | ||
| 39 | |||
| 40 | int indent; | ||
| 41 | struct Scope | ||
| 42 | { | ||
| 43 | Scope() | ||
| 44 | { | ||
| 45 | localObjIndex = 0; | ||
| 46 | localFnIndex = 0; | ||
| 47 | localBaseIndex = 0; | ||
| 48 | localWithIndex = 0; | ||
| 49 | } | ||
| 50 | int localObjIndex; | ||
| 51 | int localFnIndex; | ||
| 52 | int localBaseIndex; | ||
| 53 | int localWithIndex; | ||
| 54 | std::vector<std::string> locals; | ||
| 55 | }; | ||
| 56 | |||
| 57 | std::string getNewLocalObj() | ||
| 58 | { | ||
| 59 | temp << "_obj_" << scope().localObjIndex; | ||
| 60 | scope().localObjIndex++; | ||
| 61 | std::string local = temp.str(); | ||
| 62 | temp.str(""); | ||
| 63 | temp.clear(); | ||
| 64 | return local; | ||
| 65 | } | ||
| 66 | |||
| 67 | std::string getNewLocalFn() | ||
| 68 | { | ||
| 69 | temp << "_fn_" << scope().localObjIndex; | ||
| 70 | scope().localFnIndex++; | ||
| 71 | std::string local = temp.str(); | ||
| 72 | temp.str(""); | ||
| 73 | temp.clear(); | ||
| 74 | return local; | ||
| 75 | } | ||
| 76 | |||
| 77 | std::string getNewLocalBase() | ||
| 78 | { | ||
| 79 | temp << "_base_" << scope().localBaseIndex; | ||
| 80 | scope().localBaseIndex++; | ||
| 81 | std::string local = temp.str(); | ||
| 82 | temp.str(""); | ||
| 83 | temp.clear(); | ||
| 84 | return local; | ||
| 85 | } | ||
| 86 | |||
| 87 | bool isLocal(const std::string& var) | ||
| 88 | { | ||
| 89 | return _localVars.find(var) != _localVars.end(); | ||
| 90 | } | ||
| 91 | |||
| 92 | void putLocal(const std::string& var) | ||
| 93 | { | ||
| 94 | if (_localVars.find(var) == _localVars.end()) | ||
| 95 | { | ||
| 96 | _localVars.insert(var); | ||
| 97 | _scopeStack.top().locals.push_back(var); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | void pushScope() | ||
| 102 | { | ||
| 103 | int lastWithIndex = scope().localWithIndex; | ||
| 104 | _scopeStack.emplace(); | ||
| 105 | scope().localWithIndex = lastWithIndex + 1; | ||
| 106 | indent++; | ||
| 107 | } | ||
| 108 | |||
| 109 | Scope& scope() | ||
| 110 | { | ||
| 111 | return _scopeStack.top(); | ||
| 112 | } | ||
| 113 | |||
| 114 | void popScope() | ||
| 115 | { | ||
| 116 | const auto& scope = _scopeStack.top(); | ||
| 117 | for (const auto& var : scope.locals) | ||
| 118 | { | ||
| 119 | _localVars.erase(var); | ||
| 120 | } | ||
| 121 | _scopeStack.pop(); | ||
| 122 | indent--; | ||
| 123 | } | ||
| 124 | private: | ||
| 125 | std::unordered_set<std::string> _localVars; | ||
| 126 | std::stack<Scope> _scopeStack; | ||
| 127 | }; | ||
| 128 | |||
| 129 | std::string& trim(std::string& s) | 10 | std::string& trim(std::string& s) |
| 130 | { | 11 | { |
| 131 | s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) | 12 | s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) |
| @@ -266,288 +147,20 @@ AST_IMPL(Line) | |||
| 266 | AST_IMPL(Block) | 147 | AST_IMPL(Block) |
| 267 | AST_IMPL(BlockEnd) | 148 | AST_IMPL(BlockEnd) |
| 268 | 149 | ||
| 269 | void Num_t::visit(void* ud) | ||
| 270 | { | ||
| 271 | Data* data = static_cast<Data*>(ud); | ||
| 272 | std::string str = data->conv.to_bytes(&*m_begin.m_it, &*m_end.m_it); | ||
| 273 | data->buffer << trim(str); | ||
| 274 | } | ||
| 275 | |||
| 276 | void _Name_t::visit(void* ud) | ||
| 277 | { | ||
| 278 | Data* data = static_cast<Data*>(ud); | ||
| 279 | data->buffer << getValue(); | ||
| 280 | } | ||
| 281 | |||
| 282 | void Name_t::visit(void* ud) | ||
| 283 | { | ||
| 284 | name->visit(ud); | ||
| 285 | } | ||
| 286 | |||
| 287 | void self_t::visit(void* ud) | ||
| 288 | { | ||
| 289 | Data* data = static_cast<Data*>(ud); | ||
| 290 | data->buffer << "self"; | ||
| 291 | } | ||
| 292 | |||
| 293 | void self_name_t::visit(void* ud) | ||
| 294 | { | ||
| 295 | Data* data = static_cast<Data*>(ud); | ||
| 296 | data->buffer << (data->callerStack.top() ? "self:" : "self."); | ||
| 297 | name->visit(ud); | ||
| 298 | } | ||
| 299 | |||
| 300 | void self_class_t::visit(void* ud) | ||
| 301 | { | ||
| 302 | Data* data = static_cast<Data*>(ud); | ||
| 303 | data->buffer << "self.__class"; | ||
| 304 | } | ||
| 305 | |||
| 306 | void self_class_name_t::visit(void* ud) | ||
| 307 | { | ||
| 308 | Data* data = static_cast<Data*>(ud); | ||
| 309 | data->buffer << (data->callerStack.top() ? "self.__class:" : "self.__class."); | ||
| 310 | name->visit(ud); | ||
| 311 | } | ||
| 312 | |||
| 313 | void SelfName_t::visit(void* ud) | ||
| 314 | { | ||
| 315 | name->visit(ud); | ||
| 316 | } | ||
| 317 | |||
| 318 | void KeyName_t::visit(void* ud) | ||
| 319 | { | ||
| 320 | name->visit(ud); | ||
| 321 | } | ||
| 322 | |||
| 323 | void VarArg_t::visit(void* ud) | ||
| 324 | { | ||
| 325 | Data* data = static_cast<Data*>(ud); | ||
| 326 | data->buffer << "..."; | ||
| 327 | } | ||
| 328 | |||
| 329 | void NameList_t::visit(void* ud) | ||
| 330 | { | ||
| 331 | Data* data = static_cast<Data*>(ud); | ||
| 332 | auto it = names.objects().begin(); | ||
| 333 | Name_t* name = *it; | ||
| 334 | name->visit(ud); | ||
| 335 | ++it; | ||
| 336 | for (; it != names.objects().end(); ++it) | ||
| 337 | { | ||
| 338 | name = *it; | ||
| 339 | data->buffer << ", "; | ||
| 340 | name->visit(ud); | ||
| 341 | } | ||
| 342 | } | ||
| 343 | |||
| 344 | void Import_t::visit(void* ud) | ||
| 345 | { | ||
| 346 | Data* data = static_cast<Data*>(ud); | ||
| 347 | std::vector<std::tuple<const std::string*, bool>> nameItems; | ||
| 348 | nameItems.reserve(names.objects().size()); | ||
| 349 | for (ImportName_t* importName : names.objects()) | ||
| 350 | { | ||
| 351 | if (Name_t* name = ast_cast<Name_t>(importName->name)) | ||
| 352 | { | ||
| 353 | nameItems.push_back(std::make_tuple(&name->name->getValue(), false)); | ||
| 354 | } | ||
| 355 | else | ||
| 356 | { | ||
| 357 | colon_import_name_t* colonName = ast_cast<colon_import_name_t>(importName->name); | ||
| 358 | nameItems.push_back(std::make_tuple(&colonName->name->name->getValue(), true)); | ||
| 359 | } | ||
| 360 | } | ||
| 361 | data->buffer << "local "; | ||
| 362 | for (const auto& item : nameItems) | ||
| 363 | { | ||
| 364 | data->buffer << *std::get<0>(item); | ||
| 365 | if (&item != &nameItems.back()) | ||
| 366 | { | ||
| 367 | data->buffer << ", "; | ||
| 368 | } | ||
| 369 | } | ||
| 370 | data->endLine(); | ||
| 371 | |||
| 372 | data->beginLine(); | ||
| 373 | data->pushScope(); | ||
| 374 | data->buffer << "do"; | ||
| 375 | data->endLine(); | ||
| 376 | |||
| 377 | std::string fromObj = data->getNewLocalObj(); | ||
| 378 | |||
| 379 | data->beginLine(); | ||
| 380 | data->buffer << "local " << fromObj << " = "; | ||
| 381 | exp->visit(ud); | ||
| 382 | data->endLine(); | ||
| 383 | |||
| 384 | data->beginLine(); | ||
| 385 | for (const auto& item : nameItems) | ||
| 386 | { | ||
| 387 | data->buffer << *std::get<0>(item); | ||
| 388 | if (&item != &nameItems.back()) | ||
| 389 | { | ||
| 390 | data->buffer << ", "; | ||
| 391 | } | ||
| 392 | } | ||
| 393 | data->buffer << " = "; | ||
| 394 | for (const auto& item : nameItems) | ||
| 395 | { | ||
| 396 | if (std::get<1>(item)) | ||
| 397 | { | ||
| 398 | data->pushScope(); | ||
| 399 | data->buffer << "(function()"; | ||
| 400 | data->endLine(); | ||
| 401 | |||
| 402 | std::string varBase = data->getNewLocalBase(); | ||
| 403 | |||
| 404 | data->beginLine(); | ||
| 405 | data->buffer << "local " << varBase << " = " << fromObj; | ||
| 406 | data->endLine(); | ||
| 407 | |||
| 408 | std::string varFn = data->getNewLocalFn(); | ||
| 409 | |||
| 410 | data->beginLine(); | ||
| 411 | data->buffer << "local " << varFn << " = " << varBase << '.' << *std::get<0>(item); | ||
| 412 | data->endLine(); | ||
| 413 | |||
| 414 | data->beginLine(); | ||
| 415 | data->buffer << "return function(...)"; | ||
| 416 | data->endLine(); | ||
| 417 | |||
| 418 | data->beginLine(); | ||
| 419 | data->pushScope(); | ||
| 420 | data->buffer << varFn << '(' << varBase << ", ...)"; | ||
| 421 | data->endLine(); | ||
| 422 | |||
| 423 | data->beginLine(); | ||
| 424 | data->buffer << "end"; | ||
| 425 | data->popScope(); | ||
| 426 | data->endLine(); | ||
| 427 | |||
| 428 | data->beginLine(); | ||
| 429 | data->buffer << "end)()"; | ||
| 430 | data->popScope(); | ||
| 431 | } | ||
| 432 | else | ||
| 433 | { | ||
| 434 | data->buffer << fromObj << '.' << *std::get<0>(item); | ||
| 435 | } | ||
| 436 | if (&item != &nameItems.back()) | ||
| 437 | { | ||
| 438 | data->buffer << ", "; | ||
| 439 | } | ||
| 440 | } | ||
| 441 | data->endLine(); | ||
| 442 | |||
| 443 | data->beginLine(); | ||
| 444 | data->buffer << "end"; | ||
| 445 | data->popScope(); | ||
| 446 | } | ||
| 447 | |||
| 448 | void ExpListLow_t::visit(void* ud) | ||
| 449 | { | ||
| 450 | Data* data = static_cast<Data*>(ud); | ||
| 451 | for (Exp_t* expr : exprs.objects()) | ||
| 452 | { | ||
| 453 | expr->visit(ud); | ||
| 454 | if (expr != exprs.objects().back()) | ||
| 455 | { | ||
| 456 | data->buffer << ", "; | ||
| 457 | } | ||
| 458 | } | ||
| 459 | } | ||
| 460 | |||
| 461 | void ExpList_t::visit(void* ud) | ||
| 462 | { | ||
| 463 | Data* data = static_cast<Data*>(ud); | ||
| 464 | for (Exp_t* expr : exprs.objects()) | ||
| 465 | { | ||
| 466 | expr->visit(ud); | ||
| 467 | if (expr != exprs.objects().back()) | ||
| 468 | { | ||
| 469 | data->buffer << ", "; | ||
| 470 | } | ||
| 471 | } | ||
| 472 | } | ||
| 473 | |||
| 474 | void Return_t::visit(void* ud) | ||
| 475 | { | ||
| 476 | Data* data = static_cast<Data*>(ud); | ||
| 477 | data->buffer << "return"; | ||
| 478 | if (valueList && !valueList->exprs.objects().empty()) | ||
| 479 | { | ||
| 480 | data->buffer << ' '; | ||
| 481 | valueList->visit(ud); | ||
| 482 | } | ||
| 483 | } | ||
| 484 | |||
| 485 | void With_t::visit(void* ud) | ||
| 486 | { | ||
| 487 | Data* data = static_cast<Data*>(ud); | ||
| 488 | data->buffer << "return"; | ||
| 489 | for (Exp_t* expr : valueList->exprs.objects()) | ||
| 490 | { | ||
| 491 | if (assigns && (!expr->opValues.objects().empty() || expr->value->getFlattened())) | ||
| 492 | { | ||
| 493 | throw std::logic_error("left hand expression is not assignable."); | ||
| 494 | } | ||
| 495 | // TODO | ||
| 496 | } | ||
| 497 | if (valueList && !valueList->exprs.objects().empty()) | ||
| 498 | { | ||
| 499 | data->buffer << ' '; | ||
| 500 | valueList->visit(ud); | ||
| 501 | } | ||
| 502 | } | ||
| 503 | |||
| 504 | ast_node* Value_t::getFlattened() | ||
| 505 | { | ||
| 506 | if (SimpleValue_t* simpleValue = ast_cast<SimpleValue_t>(item)) | ||
| 507 | { | ||
| 508 | return simpleValue->value; | ||
| 509 | } | ||
| 510 | else if (simple_table_t* simple_table = ast_cast<simple_table_t>(item)) | ||
| 511 | { | ||
| 512 | return simple_table; | ||
| 513 | } | ||
| 514 | else if (ChainValue_t* chainValue = ast_cast<ChainValue_t>(item)) | ||
| 515 | { | ||
| 516 | if (chainValue->arguments) | ||
| 517 | { | ||
| 518 | return chainValue; | ||
| 519 | } | ||
| 520 | else | ||
| 521 | { | ||
| 522 | if (Chain_t* chain = ast_cast<Chain_t>(chainValue->caller)) | ||
| 523 | { | ||
| 524 | return chain->item; | ||
| 525 | } | ||
| 526 | else if (Callable_t* callable = ast_cast<Callable_t>(chainValue->caller)) | ||
| 527 | { | ||
| 528 | return callable->item; | ||
| 529 | } | ||
| 530 | } | ||
| 531 | } | ||
| 532 | return item; | ||
| 533 | } | ||
| 534 | |||
| 535 | #include <iostream> | 150 | #include <iostream> |
| 536 | 151 | ||
| 537 | int main() | 152 | int main() |
| 538 | { | 153 | { |
| 539 | std::wstring_convert<deletable_facet<std::codecvt<char32_t, char, std::mbstate_t>>, char32_t> conv; | 154 | std::wstring_convert<deletable_facet<std::codecvt<char32_t, char, std::mbstate_t>>, char32_t> conv; |
| 540 | std::string s = R"baddog(import \x, func, \memFunc from require "utils")baddog"; | 155 | std::string s = R"TestCodesHere()TestCodesHere"; |
| 541 | input i = conv.from_bytes(s); | 156 | input i = conv.from_bytes(s); |
| 542 | 157 | ||
| 543 | error_list el; | 158 | error_list el; |
| 544 | Import_t* root = nullptr; | 159 | BlockEnd_t* root = nullptr; |
| 545 | State st; | 160 | State st; |
| 546 | if (parse(i, Import, el, root, &st)) | 161 | if (parse(i, BlockEnd, el, root, &st)) |
| 547 | { | 162 | { |
| 548 | std::cout << "matched!\n"; | 163 | std::cout << "matched!\n"; |
| 549 | Data data; | ||
| 550 | root->visit(&data); | ||
| 551 | } | 164 | } |
| 552 | else | 165 | else |
| 553 | { | 166 | { |
