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 'src/MoonP/moon_parser.cpp')
-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 << |