diff options
Diffstat (limited to '')
| -rw-r--r-- | src/yuescript/yue_parser.cpp | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 1b72a8c..1999721 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
| @@ -50,6 +50,15 @@ public: | |||
| 50 | } \ | 50 | } \ |
| 51 | } while (false) | 51 | } while (false) |
| 52 | 52 | ||
| 53 | #define RaiseErrorI(msg, item) \ | ||
| 54 | do { \ | ||
| 55 | if (reinterpret_cast<State*>(item.user_data)->lax) { \ | ||
| 56 | return -1; \ | ||
| 57 | } else { \ | ||
| 58 | throw ParserError(msg, item.begin); \ | ||
| 59 | } \ | ||
| 60 | } while (false) | ||
| 61 | |||
| 53 | // clang-format off | 62 | // clang-format off |
| 54 | YueParser::YueParser() { | 63 | YueParser::YueParser() { |
| 55 | plain_space = *set(" \t"); | 64 | plain_space = *set(" \t"); |
| @@ -316,14 +325,14 @@ YueParser::YueParser() { | |||
| 316 | for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) { | 325 | for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) { |
| 317 | switch (*i) { | 326 | switch (*i) { |
| 318 | case '\t': indent += 4; break; | 327 | case '\t': indent += 4; break; |
| 319 | default: RaiseError("can not mix the use of tabs and spaces as indents"sv, item); break; | 328 | default: RaiseErrorI("can not mix the use of tabs and spaces as indents"sv, item); break; |
| 320 | } | 329 | } |
| 321 | } | 330 | } |
| 322 | } else { | 331 | } else { |
| 323 | for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) { | 332 | for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) { |
| 324 | switch (*i) { | 333 | switch (*i) { |
| 325 | case ' ': indent++; break; | 334 | case ' ': indent++; break; |
| 326 | default: RaiseError("can not mix the use of tabs and spaces as indents"sv, item); break; | 335 | default: RaiseErrorI("can not mix the use of tabs and spaces as indents"sv, item); break; |
| 327 | } | 336 | } |
| 328 | } | 337 | } |
| 329 | } | 338 | } |
| @@ -357,6 +366,12 @@ YueParser::YueParser() { | |||
| 357 | } | 366 | } |
| 358 | } | 367 | } |
| 359 | State* st = reinterpret_cast<State*>(item.user_data); | 368 | State* st = reinterpret_cast<State*>(item.user_data); |
| 369 | if (st->indents.empty()) { | ||
| 370 | RaiseError("unknown indent level"sv, item); | ||
| 371 | } | ||
| 372 | if (st->indents.top() > indent) { | ||
| 373 | RaiseError("unexpected dedent"sv, item); | ||
| 374 | } | ||
| 360 | st->indents.push(indent); | 375 | st->indents.push(indent); |
| 361 | return true; | 376 | return true; |
| 362 | }); | 377 | }); |
| @@ -1014,16 +1029,24 @@ YueParser::YueParser() { | |||
| 1014 | 1029 | ||
| 1015 | FnArgDef = (Variable | SelfItem >> -ExistentialOp) >> -(space >> '`' >> space >> Name) >> -(space >> '=' >> space >> Exp) | TableLit | SimpleTable; | 1030 | FnArgDef = (Variable | SelfItem >> -ExistentialOp) >> -(space >> '`' >> space >> Name) >> -(space >> '=' >> space >> Exp) | TableLit | SimpleTable; |
| 1016 | 1031 | ||
| 1017 | check_vararg_position = and_(white >> ')') | white >> -(',' >> white) >> vararg_position_error; | 1032 | check_vararg_position = and_(white >> (')' | key("using"))) | white >> -(',' >> white) >> vararg_position_error; |
| 1018 | 1033 | ||
| 1019 | FnArgDefList = Seperator >> ( | 1034 | var_arg_def = ( |
| 1020 | fn_arg_def_lit_lines >> -(-(space >> ',') >> white >> VarArg >> -(space >> '`' >> space >> Name) >> check_vararg_position) | | 1035 | VarArg | |
| 1021 | white >> VarArg >> -(space >> '`' >> space >> Name) >> check_vararg_position | 1036 | +space_break >> push_indent_match >> ensure(space >> VarArg >> -(space >> '`' >> space >> Name), pop_indent) |
| 1022 | ); | 1037 | ) >> check_vararg_position; |
| 1038 | |||
| 1039 | FnArgDefList = Seperator >> | ||
| 1040 | -fn_arg_def_list >> | ||
| 1041 | -(-(space >> ',') >> +space_break >> fn_arg_def_lit_lines) >> | ||
| 1042 | -(-(space >> ',') >> space >> var_arg_def); | ||
| 1023 | 1043 | ||
| 1024 | OuterVarShadow = key("using") >> space >> (key("nil") | NameList); | 1044 | OuterVarShadow = key("using") >> space >> (key("nil") | NameList); |
| 1025 | 1045 | ||
| 1026 | FnArgsDef = '(' >> *space_break >> -FnArgDefList >> -(white >> OuterVarShadow) >> white >> -(and_(',') >> unexpected_comma_error) >> ')'; | 1046 | outer_var_shadow_def = OuterVarShadow | |
| 1047 | +space_break >> push_indent_match >> ensure(space >> OuterVarShadow, pop_indent); | ||
| 1048 | |||
| 1049 | FnArgsDef = '(' >> space >> -FnArgDefList >> -(space >> outer_var_shadow_def) >> white >> -(and_(',') >> unexpected_comma_error) >> ')'; | ||
| 1027 | FnArrow = expr("->") | "=>"; | 1050 | FnArrow = expr("->") | "=>"; |
| 1028 | FunLit = pl::user(true_(), [](const item_t& item) { | 1051 | FunLit = pl::user(true_(), [](const item_t& item) { |
| 1029 | State* st = reinterpret_cast<State*>(item.user_data); | 1052 | State* st = reinterpret_cast<State*>(item.user_data); |
| @@ -1035,11 +1058,11 @@ YueParser::YueParser() { | |||
| 1035 | ) >> space >> FnArrow >> -(space >> Body); | 1058 | ) >> space >> FnArrow >> -(space >> Body); |
| 1036 | 1059 | ||
| 1037 | MacroName = '$' >> UnicodeName; | 1060 | MacroName = '$' >> UnicodeName; |
| 1038 | macro_args_def = '(' >> white >> -FnArgDefList >> white >> -(and_(',') >> unexpected_comma_error) >> ')'; | 1061 | macro_args_def = '(' >> space >> -FnArgDefList >> white >> -(and_(',') >> unexpected_comma_error) >> ')'; |
| 1039 | MacroLit = -(macro_args_def >> space) >> "->" >> space >> Body; | 1062 | MacroLit = -(macro_args_def >> space) >> "->" >> space >> Body; |
| 1040 | MacroFunc = MacroName >> (Invoke | InvokeArgs); | 1063 | MacroFunc = MacroName >> (Invoke | InvokeArgs); |
| 1041 | Macro = key("macro") >> space >> ( | 1064 | Macro = key("macro") >> space >> ( |
| 1042 | UnicodeName >> space >> '=' >> space >> (MacroLit | MacroFunc | expected_expression_error) | | 1065 | UnicodeName >> space >> '=' >> space >> (MacroLit | MacroFunc | invalid_macro_definition_error) | |
| 1043 | invalid_macro_definition_error | 1066 | invalid_macro_definition_error |
| 1044 | ); | 1067 | ); |
| 1045 | MacroInPlace = '$' >> space >> "->" >> space >> Body; | 1068 | MacroInPlace = '$' >> space >> "->" >> space >> Body; |
