diff options
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 { |