diff options
| author | Li Jin <dragon-fly@qq.com> | 2020-03-05 16:08:41 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2020-03-05 16:08:41 +0800 |
| commit | 890fc913737c62c5d7e51636e0535b7b318a0d89 (patch) | |
| tree | 8ca71fc3a2599ad1cbebcd3234dcb06292448037 /src/MoonP/moon_parser.cpp | |
| parent | 3b94999e55df35d19616e87d7f3b6fddf5b8a30b (diff) | |
| download | yuescript-890fc913737c62c5d7e51636e0535b7b318a0d89.tar.gz yuescript-890fc913737c62c5d7e51636e0535b7b318a0d89.tar.bz2 yuescript-890fc913737c62c5d7e51636e0535b7b318a0d89.zip | |
move functions of old export statement to global statement, make export statement work with Lua module system.
Diffstat (limited to '')
| -rw-r--r-- | src/MoonP/moon_parser.cpp | 74 |
1 files changed, 49 insertions, 25 deletions
diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp index fecf869..baa8eff 100644 --- a/src/MoonP/moon_parser.cpp +++ b/src/MoonP/moon_parser.cpp | |||
| @@ -28,8 +28,8 @@ std::unordered_set<std::string> Keywords = { | |||
| 28 | "repeat", "return", "then", "true", "until", | 28 | "repeat", "return", "then", "true", "until", |
| 29 | "while", // Lua keywords | 29 | "while", // Lua keywords |
| 30 | "as", "class", "continue", "export", "extends", | 30 | "as", "class", "continue", "export", "extends", |
| 31 | "from", "import", "switch", "unless", "using", | 31 | "from", "global", "import", "switch", "unless", |
| 32 | "when", "with" // Moon keywords | 32 | "using", "when", "with" // Moon keywords |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | MoonParser::MoonParser() { | 35 | MoonParser::MoonParser() { |
| @@ -74,9 +74,15 @@ MoonParser::MoonParser() { | |||
| 74 | Variable = pl::user(Name, [](const item_t& item) { | 74 | Variable = pl::user(Name, [](const item_t& item) { |
| 75 | State* st = reinterpret_cast<State*>(item.user_data); | 75 | State* st = reinterpret_cast<State*>(item.user_data); |
| 76 | for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast<char>(*it); | 76 | for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast<char>(*it); |
| 77 | auto it = Keywords.find(st->buffer); | 77 | auto isValid = Keywords.find(st->buffer) == Keywords.end(); |
| 78 | if (isValid) { | ||
| 79 | if (st->buffer == st->moduleName) { | ||
| 80 | st->moduleFix++; | ||
| 81 | st->moduleName = std::string("_module_"sv) + std::to_string(st->moduleFix); | ||
| 82 | } | ||
| 83 | } | ||
| 78 | st->buffer.clear(); | 84 | st->buffer.clear(); |
| 79 | return it == Keywords.end(); | 85 | return isValid; |
| 80 | }); | 86 | }); |
| 81 | 87 | ||
| 82 | LuaKeyword = pl::user(Name, [](const item_t& item) { | 88 | LuaKeyword = pl::user(Name, [](const item_t& item) { |
| @@ -153,7 +159,7 @@ MoonParser::MoonParser() { | |||
| 153 | return true; | 159 | return true; |
| 154 | }); | 160 | }); |
| 155 | 161 | ||
| 156 | InBlock = Advance >> Block >> PopIndent; | 162 | InBlock = Advance >> ensure(Block, PopIndent); |
| 157 | 163 | ||
| 158 | local_flag = expr('*') | expr('^'); | 164 | local_flag = expr('*') | expr('^'); |
| 159 | Local = key("local") >> ((Space >> local_flag) | NameList); | 165 | Local = key("local") >> ((Space >> local_flag) | NameList); |
| @@ -211,21 +217,18 @@ MoonParser::MoonParser() { | |||
| 211 | DisableDo >> ensure(for_in, PopDo) >> | 217 | DisableDo >> ensure(for_in, PopDo) >> |
| 212 | -key("do") >> Body; | 218 | -key("do") >> Body; |
| 213 | 219 | ||
| 214 | Do = pl::user(key("do") >> Body, [](const item_t& item) | 220 | Do = pl::user(key("do"), [](const item_t& item) { |
| 215 | { | ||
| 216 | State* st = reinterpret_cast<State*>(item.user_data); | 221 | State* st = reinterpret_cast<State*>(item.user_data); |
| 217 | return st->doStack.empty() || st->doStack.top(); | 222 | return st->doStack.empty() || st->doStack.top(); |
| 218 | }); | 223 | }) >> Body; |
| 219 | 224 | ||
| 220 | DisableDo = pl::user(true_(), [](const item_t& item) | 225 | DisableDo = pl::user(true_(), [](const item_t& item) { |
| 221 | { | ||
| 222 | State* st = reinterpret_cast<State*>(item.user_data); | 226 | State* st = reinterpret_cast<State*>(item.user_data); |
| 223 | st->doStack.push(false); | 227 | st->doStack.push(false); |
| 224 | return true; | 228 | return true; |
| 225 | }); | 229 | }); |
| 226 | 230 | ||
| 227 | PopDo = pl::user(true_(), [](const item_t& item) | 231 | PopDo = pl::user(true_(), [](const item_t& item) { |
| 228 | { | ||
| 229 | State* st = reinterpret_cast<State*>(item.user_data); | 232 | State* st = reinterpret_cast<State*>(item.user_data); |
| 230 | st->doStack.pop(); | 233 | st->doStack.pop(); |
| 231 | return true; | 234 | return true; |
| @@ -312,11 +315,7 @@ MoonParser::MoonParser() { | |||
| 312 | 315 | ||
| 313 | LuaStringContent = *(not_(LuaStringClose) >> Any); | 316 | LuaStringContent = *(not_(LuaStringClose) >> Any); |
| 314 | 317 | ||
| 315 | LuaString = pl::user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose, [](const item_t& item) { | 318 | LuaString = LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose; |
| 316 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 317 | st->stringOpen = -1; | ||
| 318 | return true; | ||
| 319 | }); | ||
| 320 | 319 | ||
| 321 | Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')'); | 320 | Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')'); |
| 322 | Callable = Space >> Variable | SelfName | VarArg | Parens; | 321 | Callable = Space >> Variable | SelfName | VarArg | Parens; |
| @@ -392,9 +391,30 @@ MoonParser::MoonParser() { | |||
| 392 | -(key("extends") >> PreventIndent >> ensure(Exp, PopIndent)) >> | 391 | -(key("extends") >> PreventIndent >> ensure(Exp, PopIndent)) >> |
| 393 | -ClassBlock; | 392 | -ClassBlock; |
| 394 | 393 | ||
| 395 | export_values = NameList >> -(sym('=') >> ExpListLow); | 394 | global_values = NameList >> -(sym('=') >> ExpListLow); |
| 396 | export_op = expr('*') | expr('^'); | 395 | global_op = expr('*') | expr('^'); |
| 397 | Export = key("export") >> (ClassDecl | (Space >> export_op) | export_values); | 396 | Global = key("global") >> (ClassDecl | (Space >> global_op) | global_values); |
| 397 | |||
| 398 | export_default = key("default"); | ||
| 399 | |||
| 400 | Export = pl::user(key("export"), [](const item_t& item) { | ||
| 401 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 402 | st->exportCount++; | ||
| 403 | return true; | ||
| 404 | }) >> ((pl::user(export_default, [](const item_t& item) { | ||
| 405 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 406 | bool isValid = !st->exportDefault && st->exportCount == 1; | ||
| 407 | st->exportDefault = true; | ||
| 408 | return isValid; | ||
| 409 | }) >> Exp) | ||
| 410 | | (pl::user(true_(), [](const item_t& item) { | ||
| 411 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 412 | if (st->exportDefault && st->exportCount > 1) { | ||
| 413 | return false; | ||
| 414 | } else { | ||
| 415 | return true; | ||
| 416 | } | ||
| 417 | }) >> ExpList >> -Assign)) >> not_(Space >> statement_appendix); | ||
| 398 | 418 | ||
| 399 | variable_pair = sym(':') >> Variable; | 419 | variable_pair = sym(':') >> Variable; |
| 400 | 420 | ||
| @@ -479,12 +499,12 @@ MoonParser::MoonParser() { | |||
| 479 | statement_appendix = (if_else_line | unless_line | CompInner) >> Space; | 499 | statement_appendix = (if_else_line | unless_line | CompInner) >> Space; |
| 480 | Statement = ( | 500 | Statement = ( |
| 481 | Import | While | For | ForEach | | 501 | Import | While | For | ForEach | |
| 482 | Return | Local | Export | Space >> BreakLoop | | 502 | Return | Local | Global | Export | Space >> BreakLoop | |
| 483 | Backcall | ExpListAssign | 503 | Backcall | ExpListAssign |
| 484 | ) >> Space >> | 504 | ) >> Space >> |
| 485 | -statement_appendix; | 505 | -statement_appendix; |
| 486 | 506 | ||
| 487 | Body = -Space >> Break >> *EmptyLine >> InBlock | Statement; | 507 | Body = Space >> Break >> *EmptyLine >> InBlock | Statement; |
| 488 | 508 | ||
| 489 | empty_line_stop = Space >> and_(Stop); | 509 | empty_line_stop = Space >> and_(Stop); |
| 490 | Line = CheckIndent >> Statement | empty_line_stop; | 510 | Line = CheckIndent >> Statement | empty_line_stop; |
| @@ -498,7 +518,7 @@ ParseInfo MoonParser::parse(std::string_view codes, rule& r) { | |||
| 498 | ParseInfo res; | 518 | ParseInfo res; |
| 499 | try { | 519 | try { |
| 500 | res.codes = std::make_unique<input>(); | 520 | res.codes = std::make_unique<input>(); |
| 501 | *(res.codes) = _converter.from_bytes(codes.begin(), codes.end()); | 521 | *(res.codes) = _converter.from_bytes(&codes.front(), &codes.back() + 1); |
| 502 | } catch (const std::range_error&) { | 522 | } catch (const std::range_error&) { |
| 503 | res.error = "Invalid text encoding."sv; | 523 | res.error = "Invalid text encoding."sv; |
| 504 | return res; | 524 | return res; |
| @@ -507,6 +527,10 @@ ParseInfo MoonParser::parse(std::string_view codes, rule& r) { | |||
| 507 | try { | 527 | try { |
| 508 | State state; | 528 | State state; |
| 509 | res.node.set(pl::parse(*(res.codes), r, errors, &state)); | 529 | res.node.set(pl::parse(*(res.codes), r, errors, &state)); |
| 530 | if (state.exportCount > 0) { | ||
| 531 | res.moduleName = std::move(state.moduleName); | ||
| 532 | res.exportDefault = state.exportDefault; | ||
| 533 | } | ||
| 510 | } catch (const std::logic_error& err) { | 534 | } catch (const std::logic_error& err) { |
| 511 | res.error = err.what(); | 535 | res.error = err.what(); |
| 512 | return res; | 536 | return res; |
| @@ -538,7 +562,7 @@ std::string MoonParser::toString(input::iterator begin, input::iterator end) { | |||
| 538 | } | 562 | } |
| 539 | 563 | ||
| 540 | input MoonParser::encode(std::string_view codes) { | 564 | input MoonParser::encode(std::string_view codes) { |
| 541 | return _converter.from_bytes(codes.begin(), codes.end()); | 565 | return _converter.from_bytes(&codes.front(), &codes.back() + 1); |
| 542 | } | 566 | } |
| 543 | 567 | ||
| 544 | std::string MoonParser::decode(const input& codes) { | 568 | std::string MoonParser::decode(const input& codes) { |
| @@ -572,7 +596,6 @@ std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc | |||
| 572 | count++; | 596 | count++; |
| 573 | } | 597 | } |
| 574 | } | 598 | } |
| 575 | auto line = Converter{}.to_bytes(std::wstring(begin, end)); | ||
| 576 | int oldCol = loc->m_begin.m_col; | 599 | int oldCol = loc->m_begin.m_col; |
| 577 | int col = std::max(0, oldCol - 1); | 600 | int col = std::max(0, oldCol - 1); |
| 578 | auto it = begin; | 601 | auto it = begin; |
| @@ -582,6 +605,7 @@ std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc | |||
| 582 | } | 605 | } |
| 583 | ++it; | 606 | ++it; |
| 584 | } | 607 | } |
| 608 | auto line = Converter{}.to_bytes(std::wstring(begin, end)); | ||
| 585 | Utils::replace(line, "\t"sv, " "sv); | 609 | Utils::replace(line, "\t"sv, " "sv); |
| 586 | std::ostringstream buf; | 610 | std::ostringstream buf; |
| 587 | buf << loc->m_begin.m_line << ": "sv << msg << | 611 | buf << loc->m_begin.m_line << ": "sv << msg << |
