aboutsummaryrefslogtreecommitdiff
path: root/src/yuescript/yue_parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/yuescript/yue_parser.cpp43
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
54YueParser::YueParser() { 63YueParser::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;