diff options
| author | Li Jin <dragon-fly@qq.com> | 2020-03-11 00:21:33 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2020-03-11 00:21:33 +0800 |
| commit | 1ee056eedf773ac6166247755439092e0e0a9bca (patch) | |
| tree | 1b8863338d37fe6ded7fbaecd92d76cdb3801ab3 /src/MoonP/moon_parser.cpp | |
| parent | 015af4b70cd751e1c1580fd542997a796e1ca225 (diff) | |
| download | yuescript-1ee056eedf773ac6166247755439092e0e0a9bca.tar.gz yuescript-1ee056eedf773ac6166247755439092e0e0a9bca.tar.bz2 yuescript-1ee056eedf773ac6166247755439092e0e0a9bca.zip | |
add macro functions.
Diffstat (limited to 'src/MoonP/moon_parser.cpp')
| -rw-r--r-- | src/MoonP/moon_parser.cpp | 68 |
1 files changed, 51 insertions, 17 deletions
diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp index baa8eff..f0269d7 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", "global", "import", "switch", "unless", | 31 | "from", "global", "import", "macro", "switch", |
| 32 | "using", "when", "with" // Moon keywords | 32 | "unless", "using", "when", "with" // Moon keywords |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | MoonParser::MoonParser() { | 35 | MoonParser::MoonParser() { |
| @@ -98,9 +98,9 @@ MoonParser::MoonParser() { | |||
| 98 | self_class = expr("@@"); | 98 | self_class = expr("@@"); |
| 99 | self_class_name = "@@" >> Name; | 99 | self_class_name = "@@" >> Name; |
| 100 | 100 | ||
| 101 | SelfName = Space >> (self_class_name | self_class | self_name | self); | 101 | SelfName = self_class_name | self_class | self_name | self; |
| 102 | KeyName = SelfName | Space >> Name; | 102 | KeyName = Space >> (SelfName | Name); |
| 103 | VarArg = Space >> "..."; | 103 | VarArg = expr("..."); |
| 104 | 104 | ||
| 105 | check_indent = pl::user(Indent, [](const item_t& item) { | 105 | check_indent = pl::user(Indent, [](const item_t& item) { |
| 106 | int indent = 0; | 106 | int indent = 0; |
| @@ -162,7 +162,8 @@ MoonParser::MoonParser() { | |||
| 162 | InBlock = Advance >> ensure(Block, PopIndent); | 162 | InBlock = Advance >> ensure(Block, PopIndent); |
| 163 | 163 | ||
| 164 | local_flag = expr('*') | expr('^'); | 164 | local_flag = expr('*') | expr('^'); |
| 165 | Local = key("local") >> ((Space >> local_flag) | NameList); | 165 | local_values = NameList >> -(sym('=') >> ExpListLow); |
| 166 | Local = key("local") >> (Space >> local_flag | local_values); | ||
| 166 | 167 | ||
| 167 | colon_import_name = sym('\\') >> Space >> Variable; | 168 | colon_import_name = sym('\\') >> Space >> Variable; |
| 168 | ImportName = colon_import_name | Space >> Variable; | 169 | ImportName = colon_import_name | Space >> Variable; |
| @@ -173,9 +174,23 @@ MoonParser::MoonParser() { | |||
| 173 | ImportLiteral = sym('\'') >> import_literal_chain >> symx('\'') | sym('"') >> import_literal_chain >> symx('"'); | 174 | ImportLiteral = sym('\'') >> import_literal_chain >> symx('\'') | sym('"') >> import_literal_chain >> symx('"'); |
| 174 | 175 | ||
| 175 | ImportFrom = ImportNameList >> *SpaceBreak >> key("from") >> Exp; | 176 | ImportFrom = ImportNameList >> *SpaceBreak >> key("from") >> Exp; |
| 176 | ImportAs = ImportLiteral >> -(key("as") >> (Space >> Variable | TableLit)); | 177 | |
| 178 | EnableMacroPair = pl::user(true_(), [](const item_t& item) { | ||
| 179 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 180 | st->macroPairEnabled = true; | ||
| 181 | return true; | ||
| 182 | }); | ||
| 183 | |||
| 184 | DiableMacroPair = pl::user(true_(), [](const item_t& item) { | ||
| 185 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 186 | st->macroPairEnabled = false; | ||
| 187 | return true; | ||
| 188 | }); | ||
| 189 | |||
| 190 | ImportAs = ImportLiteral >> -(key("as") >> (Space >> Variable | EnableMacroPair >> ensure(TableLit, DiableMacroPair))); | ||
| 177 | 191 | ||
| 178 | Import = key("import") >> (ImportAs | ImportFrom); | 192 | Import = key("import") >> (ImportAs | ImportFrom); |
| 193 | |||
| 179 | BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum); | 194 | BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum); |
| 180 | 195 | ||
| 181 | Return = key("return") >> -ExpListLow; | 196 | Return = key("return") >> -ExpListLow; |
| @@ -278,7 +293,7 @@ MoonParser::MoonParser() { | |||
| 278 | 293 | ||
| 279 | BackcallOperator = expr("|>"); | 294 | BackcallOperator = expr("|>"); |
| 280 | 295 | ||
| 281 | Assignable = AssignableChain | Space >> Variable | SelfName; | 296 | Assignable = AssignableChain | Space >> Variable | Space >> SelfName; |
| 282 | 297 | ||
| 283 | exp_op_value = Space >> (BackcallOperator | BinaryOperator) >> *SpaceBreak >> Value; | 298 | exp_op_value = Space >> (BackcallOperator | BinaryOperator) >> *SpaceBreak >> Value; |
| 284 | Exp = Value >> *exp_op_value; | 299 | Exp = Value >> *exp_op_value; |
| @@ -317,8 +332,8 @@ MoonParser::MoonParser() { | |||
| 317 | 332 | ||
| 318 | LuaString = LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose; | 333 | LuaString = LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose; |
| 319 | 334 | ||
| 320 | Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')'); | 335 | Parens = symx('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')'); |
| 321 | Callable = Space >> Variable | SelfName | VarArg | Parens; | 336 | Callable = Space >> (Variable | SelfName | MacroName | VarArg | Parens); |
| 322 | FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp); | 337 | FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp); |
| 323 | 338 | ||
| 324 | FnArgs = (symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')) | | 339 | FnArgs = (symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')) | |
| @@ -414,7 +429,8 @@ MoonParser::MoonParser() { | |||
| 414 | } else { | 429 | } else { |
| 415 | return true; | 430 | return true; |
| 416 | } | 431 | } |
| 417 | }) >> ExpList >> -Assign)) >> not_(Space >> statement_appendix); | 432 | }) >> ExpList >> -Assign) |
| 433 | | Macro) >> not_(Space >> statement_appendix); | ||
| 418 | 434 | ||
| 419 | variable_pair = sym(':') >> Variable; | 435 | variable_pair = sym(':') >> Variable; |
| 420 | 436 | ||
| @@ -427,14 +443,19 @@ MoonParser::MoonParser() { | |||
| 427 | symx(':') >> | 443 | symx(':') >> |
| 428 | (Exp | TableBlock | +(SpaceBreak) >> Exp); | 444 | (Exp | TableBlock | +(SpaceBreak) >> Exp); |
| 429 | 445 | ||
| 430 | KeyValue = variable_pair | normal_pair; | 446 | macro_name_pair = Space >> MacroName >> Space >> symx(':') >> Space >> MacroName; |
| 447 | |||
| 448 | KeyValue = variable_pair | normal_pair | pl::user(sym(':') >> MacroName | macro_name_pair, [](const item_t& item) { | ||
| 449 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 450 | return st->macroPairEnabled; | ||
| 451 | }); | ||
| 431 | 452 | ||
| 432 | KeyValueList = KeyValue >> *(sym(',') >> KeyValue); | 453 | KeyValueList = KeyValue >> *(sym(',') >> KeyValue); |
| 433 | KeyValueLine = CheckIndent >> KeyValueList >> -sym(','); | 454 | KeyValueLine = CheckIndent >> KeyValueList >> -sym(','); |
| 434 | 455 | ||
| 435 | FnArgDef = (Space >> Variable | SelfName) >> -(sym('=') >> Exp); | 456 | FnArgDef = (Variable | SelfName) >> -(sym('=') >> Space >> Exp); |
| 436 | 457 | ||
| 437 | FnArgDefList = Seperator >> ( | 458 | FnArgDefList = Space >> Seperator >> ( |
| 438 | ( | 459 | ( |
| 439 | FnArgDef >> | 460 | FnArgDef >> |
| 440 | *((sym(',') | Break) >> White >> FnArgDef) >> | 461 | *((sym(',') | Break) >> White >> FnArgDef) >> |
| @@ -450,6 +471,12 @@ MoonParser::MoonParser() { | |||
| 450 | fn_arrow = expr("->") | expr("=>"); | 471 | fn_arrow = expr("->") | expr("=>"); |
| 451 | FunLit = -FnArgsDef >> Space >> fn_arrow >> -Body; | 472 | FunLit = -FnArgsDef >> Space >> fn_arrow >> -Body; |
| 452 | 473 | ||
| 474 | MacroName = expr('$') >> Name; | ||
| 475 | macro_type = expr("expr") | expr("block"); | ||
| 476 | macro_args_def = sym('(') >> White >> -FnArgDefList >> White >> sym(')'); | ||
| 477 | MacroLit = -macro_args_def >> Space >> expr("->") >> Body; | ||
| 478 | Macro = key("macro") >> Space >> macro_type >> Space >> Name >> sym('=') >> MacroLit; | ||
| 479 | |||
| 453 | NameList = Seperator >> Space >> Variable >> *(sym(',') >> White >> Variable); | 480 | NameList = Seperator >> Space >> Variable >> *(sym(',') >> White >> Variable); |
| 454 | NameOrDestructure = Space >> Variable | TableLit; | 481 | NameOrDestructure = Space >> Variable | TableLit; |
| 455 | AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> White >> NameOrDestructure); | 482 | AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> White >> NameOrDestructure); |
| @@ -499,7 +526,8 @@ MoonParser::MoonParser() { | |||
| 499 | statement_appendix = (if_else_line | unless_line | CompInner) >> Space; | 526 | statement_appendix = (if_else_line | unless_line | CompInner) >> Space; |
| 500 | Statement = ( | 527 | Statement = ( |
| 501 | Import | While | For | ForEach | | 528 | Import | While | For | ForEach | |
| 502 | Return | Local | Global | Export | Space >> BreakLoop | | 529 | Return | Local | Global | Export | |
| 530 | Macro | Space >> BreakLoop | | ||
| 503 | Backcall | ExpListAssign | 531 | Backcall | ExpListAssign |
| 504 | ) >> Space >> | 532 | ) >> Space >> |
| 505 | -statement_appendix; | 533 | -statement_appendix; |
| @@ -541,10 +569,10 @@ ParseInfo MoonParser::parse(std::string_view codes, rule& r) { | |||
| 541 | const error& err = *it; | 569 | const error& err = *it; |
| 542 | switch (err.m_type) { | 570 | switch (err.m_type) { |
| 543 | case ERROR_TYPE::ERROR_SYNTAX_ERROR: | 571 | case ERROR_TYPE::ERROR_SYNTAX_ERROR: |
| 544 | buf << res.errorMessage("Syntax error."sv, &err); | 572 | buf << res.errorMessage("syntax error"sv, &err); |
| 545 | break; | 573 | break; |
| 546 | case ERROR_TYPE::ERROR_INVALID_EOF: | 574 | case ERROR_TYPE::ERROR_INVALID_EOF: |
| 547 | buf << res.errorMessage("Invalid EOF."sv, &err); | 575 | buf << res.errorMessage("invalid EOF"sv, &err); |
| 548 | break; | 576 | break; |
| 549 | } | 577 | } |
| 550 | } | 578 | } |
| @@ -577,6 +605,12 @@ namespace Utils { | |||
| 577 | start_pos += to.size(); | 605 | start_pos += to.size(); |
| 578 | } | 606 | } |
| 579 | } | 607 | } |
| 608 | |||
| 609 | void trim(std::string& str) { | ||
| 610 | if (str.empty()) return; | ||
| 611 | str.erase(0, str.find_first_not_of(" \t")); | ||
| 612 | str.erase(str.find_last_not_of(" \t") + 1); | ||
| 613 | } | ||
| 580 | } | 614 | } |
| 581 | 615 | ||
| 582 | std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc) const { | 616 | std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc) const { |
