From 1ee056eedf773ac6166247755439092e0e0a9bca Mon Sep 17 00:00:00 2001 From: Li Jin Date: Wed, 11 Mar 2020 00:21:33 +0800 Subject: add macro functions. --- src/MoonP/moon_parser.cpp | 68 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 17 deletions(-) (limited to 'src/MoonP/moon_parser.cpp') 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 Keywords = { "repeat", "return", "then", "true", "until", "while", // Lua keywords "as", "class", "continue", "export", "extends", - "from", "global", "import", "switch", "unless", - "using", "when", "with" // Moon keywords + "from", "global", "import", "macro", "switch", + "unless", "using", "when", "with" // Moon keywords }; MoonParser::MoonParser() { @@ -98,9 +98,9 @@ MoonParser::MoonParser() { self_class = expr("@@"); self_class_name = "@@" >> Name; - SelfName = Space >> (self_class_name | self_class | self_name | self); - KeyName = SelfName | Space >> Name; - VarArg = Space >> "..."; + SelfName = self_class_name | self_class | self_name | self; + KeyName = Space >> (SelfName | Name); + VarArg = expr("..."); check_indent = pl::user(Indent, [](const item_t& item) { int indent = 0; @@ -162,7 +162,8 @@ MoonParser::MoonParser() { InBlock = Advance >> ensure(Block, PopIndent); local_flag = expr('*') | expr('^'); - Local = key("local") >> ((Space >> local_flag) | NameList); + local_values = NameList >> -(sym('=') >> ExpListLow); + Local = key("local") >> (Space >> local_flag | local_values); colon_import_name = sym('\\') >> Space >> Variable; ImportName = colon_import_name | Space >> Variable; @@ -173,9 +174,23 @@ MoonParser::MoonParser() { ImportLiteral = sym('\'') >> import_literal_chain >> symx('\'') | sym('"') >> import_literal_chain >> symx('"'); ImportFrom = ImportNameList >> *SpaceBreak >> key("from") >> Exp; - ImportAs = ImportLiteral >> -(key("as") >> (Space >> Variable | TableLit)); + + EnableMacroPair = pl::user(true_(), [](const item_t& item) { + State* st = reinterpret_cast(item.user_data); + st->macroPairEnabled = true; + return true; + }); + + DiableMacroPair = pl::user(true_(), [](const item_t& item) { + State* st = reinterpret_cast(item.user_data); + st->macroPairEnabled = false; + return true; + }); + + ImportAs = ImportLiteral >> -(key("as") >> (Space >> Variable | EnableMacroPair >> ensure(TableLit, DiableMacroPair))); Import = key("import") >> (ImportAs | ImportFrom); + BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum); Return = key("return") >> -ExpListLow; @@ -278,7 +293,7 @@ MoonParser::MoonParser() { BackcallOperator = expr("|>"); - Assignable = AssignableChain | Space >> Variable | SelfName; + Assignable = AssignableChain | Space >> Variable | Space >> SelfName; exp_op_value = Space >> (BackcallOperator | BinaryOperator) >> *SpaceBreak >> Value; Exp = Value >> *exp_op_value; @@ -317,8 +332,8 @@ MoonParser::MoonParser() { LuaString = LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose; - Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')'); - Callable = Space >> Variable | SelfName | VarArg | Parens; + Parens = symx('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')'); + Callable = Space >> (Variable | SelfName | MacroName | VarArg | Parens); FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp); FnArgs = (symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')) | @@ -414,7 +429,8 @@ MoonParser::MoonParser() { } else { return true; } - }) >> ExpList >> -Assign)) >> not_(Space >> statement_appendix); + }) >> ExpList >> -Assign) + | Macro) >> not_(Space >> statement_appendix); variable_pair = sym(':') >> Variable; @@ -427,14 +443,19 @@ MoonParser::MoonParser() { symx(':') >> (Exp | TableBlock | +(SpaceBreak) >> Exp); - KeyValue = variable_pair | normal_pair; + macro_name_pair = Space >> MacroName >> Space >> symx(':') >> Space >> MacroName; + + KeyValue = variable_pair | normal_pair | pl::user(sym(':') >> MacroName | macro_name_pair, [](const item_t& item) { + State* st = reinterpret_cast(item.user_data); + return st->macroPairEnabled; + }); KeyValueList = KeyValue >> *(sym(',') >> KeyValue); KeyValueLine = CheckIndent >> KeyValueList >> -sym(','); - FnArgDef = (Space >> Variable | SelfName) >> -(sym('=') >> Exp); + FnArgDef = (Variable | SelfName) >> -(sym('=') >> Space >> Exp); - FnArgDefList = Seperator >> ( + FnArgDefList = Space >> Seperator >> ( ( FnArgDef >> *((sym(',') | Break) >> White >> FnArgDef) >> @@ -450,6 +471,12 @@ MoonParser::MoonParser() { fn_arrow = expr("->") | expr("=>"); FunLit = -FnArgsDef >> Space >> fn_arrow >> -Body; + MacroName = expr('$') >> Name; + macro_type = expr("expr") | expr("block"); + macro_args_def = sym('(') >> White >> -FnArgDefList >> White >> sym(')'); + MacroLit = -macro_args_def >> Space >> expr("->") >> Body; + Macro = key("macro") >> Space >> macro_type >> Space >> Name >> sym('=') >> MacroLit; + NameList = Seperator >> Space >> Variable >> *(sym(',') >> White >> Variable); NameOrDestructure = Space >> Variable | TableLit; AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> White >> NameOrDestructure); @@ -499,7 +526,8 @@ MoonParser::MoonParser() { statement_appendix = (if_else_line | unless_line | CompInner) >> Space; Statement = ( Import | While | For | ForEach | - Return | Local | Global | Export | Space >> BreakLoop | + Return | Local | Global | Export | + Macro | Space >> BreakLoop | Backcall | ExpListAssign ) >> Space >> -statement_appendix; @@ -541,10 +569,10 @@ ParseInfo MoonParser::parse(std::string_view codes, rule& r) { const error& err = *it; switch (err.m_type) { case ERROR_TYPE::ERROR_SYNTAX_ERROR: - buf << res.errorMessage("Syntax error."sv, &err); + buf << res.errorMessage("syntax error"sv, &err); break; case ERROR_TYPE::ERROR_INVALID_EOF: - buf << res.errorMessage("Invalid EOF."sv, &err); + buf << res.errorMessage("invalid EOF"sv, &err); break; } } @@ -577,6 +605,12 @@ namespace Utils { start_pos += to.size(); } } + + void trim(std::string& str) { + if (str.empty()) return; + str.erase(0, str.find_first_not_of(" \t")); + str.erase(str.find_last_not_of(" \t") + 1); + } } std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc) const { -- cgit v1.2.3-55-g6feb