aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--spec/inputs/syntax.yue4
-rw-r--r--spec/inputs/unicode/syntax.yue4
-rw-r--r--src/yuescript/yue_compiler.cpp20
-rw-r--r--src/yuescript/yue_parser.cpp43
-rw-r--r--src/yuescript/yue_parser.h2
5 files changed, 51 insertions, 22 deletions
diff --git a/spec/inputs/syntax.yue b/spec/inputs/syntax.yue
index 4c0c56c..eee518a 100644
--- a/spec/inputs/syntax.yue
+++ b/spec/inputs/syntax.yue
@@ -392,7 +392,7 @@ invokeA(
392v = { 392v = {
393 a -1 393 a -1
394 a( 394 a(
395-1) 395 -1)
396 a \ 396 a \
397- 1 397- 1
398 a-1 398 a-1
@@ -405,7 +405,7 @@ v = {
405 405
406 a ~1 406 a ~1
407 a( 407 a(
408~1) 408 ~1)
409 a \ 409 a \
410~ 1 410~ 1
411 a~1 411 a~1
diff --git a/spec/inputs/unicode/syntax.yue b/spec/inputs/unicode/syntax.yue
index 8a98416..01d5c87 100644
--- a/spec/inputs/unicode/syntax.yue
+++ b/spec/inputs/unicode/syntax.yue
@@ -376,7 +376,7 @@ with 对象
376变量v = { 376变量v = {
377 变量a -1 377 变量a -1
378 变量a( 378 变量a(
379-1) 379 -1)
380 变量a \ 380 变量a \
381- 1 381- 1
382 变量a-1 382 变量a-1
@@ -389,7 +389,7 @@ with 对象
389 389
390 变量a ~1 390 变量a ~1
391 变量a( 391 变量a(
392~1) 392 ~1)
393 变量a \ 393 变量a \
394~ 1 394~ 1
395 变量a~1 395 变量a~1
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index 753ba7b..77643d3 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -876,6 +876,10 @@ private:
876 return false; 876 return false;
877 } 877 }
878 878
879 bool isListComp(Comprehension_t* comp) const {
880 return comp->items.size() == 2 && ast_is<CompFor_t>(comp->items.back());
881 }
882
879 void markVarLocalConst(const std::string& name) { 883 void markVarLocalConst(const std::string& name) {
880 auto& scope = _scopes.back(); 884 auto& scope = _scopes.back();
881 scope.vars->insert_or_assign(name, VarType::LocalConst); 885 scope.vars->insert_or_assign(name, VarType::LocalConst);
@@ -1474,7 +1478,7 @@ private:
1474 if (simpleValue->value.is<TableLit_t>()) { 1478 if (simpleValue->value.is<TableLit_t>()) {
1475 return true; 1479 return true;
1476 } else if (auto comp = simpleValue->value.as<Comprehension_t>()) { 1480 } else if (auto comp = simpleValue->value.as<Comprehension_t>()) {
1477 if (comp->items.size() != 2 || !ast_is<CompFor_t>(comp->items.back())) { 1481 if (!isListComp(comp)) {
1478 return true; 1482 return true;
1479 } 1483 }
1480 } 1484 }
@@ -1877,7 +1881,7 @@ private:
1877 case id<Try_t>(): transformTry(static_cast<Try_t*>(value), out, ExpUsage::Common); break; 1881 case id<Try_t>(): transformTry(static_cast<Try_t*>(value), out, ExpUsage::Common); break;
1878 case id<Comprehension_t>(): { 1882 case id<Comprehension_t>(): {
1879 auto comp = static_cast<Comprehension_t*>(value); 1883 auto comp = static_cast<Comprehension_t*>(value);
1880 if (comp->items.size() == 2 && ast_is<CompFor_t>(comp->items.back())) { 1884 if (isListComp(comp)) {
1881 transformCompCommon(comp, out); 1885 transformCompCommon(comp, out);
1882 } else { 1886 } else {
1883 specialSingleValue = false; 1887 specialSingleValue = false;
@@ -2468,7 +2472,7 @@ private:
2468 case id<Comprehension_t>(): { 2472 case id<Comprehension_t>(): {
2469 auto comp = static_cast<Comprehension_t*>(value); 2473 auto comp = static_cast<Comprehension_t*>(value);
2470 auto expList = assignment->expList.get(); 2474 auto expList = assignment->expList.get();
2471 if (comp->items.size() == 2 && ast_is<CompFor_t>(comp->items.back())) { 2475 if (isListComp(comp)) {
2472 std::string preDefine = getPreDefineLine(assignment); 2476 std::string preDefine = getPreDefineLine(assignment);
2473 transformComprehension(comp, out, ExpUsage::Assignment, expList); 2477 transformComprehension(comp, out, ExpUsage::Assignment, expList);
2474 out.back().insert(0, preDefine); 2478 out.back().insert(0, preDefine);
@@ -2893,7 +2897,7 @@ private:
2893 if (auto tbA = item->get_by_path<TableLit_t>()) { 2897 if (auto tbA = item->get_by_path<TableLit_t>()) {
2894 tableItems = &tbA->values.objects(); 2898 tableItems = &tbA->values.objects();
2895 } else if (auto tbB = item->get_by_path<Comprehension_t>()) { 2899 } else if (auto tbB = item->get_by_path<Comprehension_t>()) {
2896 if (tbB->items.size() == 2 && ast_is<CompFor_t>(tbB->items.back())) { 2900 if (isListComp(tbB)) {
2897 throw CompileError("invalid destructure value"sv, tbB); 2901 throw CompileError("invalid destructure value"sv, tbB);
2898 } 2902 }
2899 tableItems = &tbB->items.objects(); 2903 tableItems = &tbB->items.objects();
@@ -2924,7 +2928,7 @@ private:
2924 } 2928 }
2925 case id<Comprehension_t>(): { 2929 case id<Comprehension_t>(): {
2926 auto table = static_cast<Comprehension_t*>(node); 2930 auto table = static_cast<Comprehension_t*>(node);
2927 if (table->items.size() == 2 && ast_is<CompFor_t>(table->items.back())) { 2931 if (isListComp(table)) {
2928 throw CompileError("invalid destructure value"sv, table); 2932 throw CompileError("invalid destructure value"sv, table);
2929 } 2933 }
2930 tableItems = &table->items.objects(); 2934 tableItems = &table->items.objects();
@@ -3295,7 +3299,7 @@ private:
3295 if (auto tab = sVal->value.as<TableLit_t>()) { 3299 if (auto tab = sVal->value.as<TableLit_t>()) {
3296 destructNode = tab; 3300 destructNode = tab;
3297 } else if (auto comp = sVal->value.as<Comprehension_t>()) { 3301 } else if (auto comp = sVal->value.as<Comprehension_t>()) {
3298 if (comp->items.size() != 2 || !ast_is<CompFor_t>(comp->items.back())) { 3302 if (!isListComp(comp)) {
3299 destructNode = comp; 3303 destructNode = comp;
3300 } 3304 }
3301 } 3305 }
@@ -7422,7 +7426,7 @@ private:
7422 } 7426 }
7423 } 7427 }
7424 } else if (auto comp = sval->value.as<Comprehension_t>()) { 7428 } else if (auto comp = sval->value.as<Comprehension_t>()) {
7425 if (comp->items.size() != 2 || !ast_is<CompFor_t>(comp->items.back())) { 7429 if (!isListComp(comp)) {
7426 discrete = inExp->new_ptr<ExpList_t>(); 7430 discrete = inExp->new_ptr<ExpList_t>();
7427 for (ast_node* val : comp->items.objects()) { 7431 for (ast_node* val : comp->items.objects()) {
7428 if (auto def = ast_cast<NormalDef_t>(val)) { 7432 if (auto def = ast_cast<NormalDef_t>(val)) {
@@ -8285,7 +8289,7 @@ private:
8285 8289
8286 void transformComprehension(Comprehension_t* comp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { 8290 void transformComprehension(Comprehension_t* comp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
8287 auto x = comp; 8291 auto x = comp;
8288 if (comp->items.size() != 2 || !ast_is<CompFor_t>(comp->items.back())) { 8292 if (!isListComp(comp)) {
8289 switch (usage) { 8293 switch (usage) {
8290 case ExpUsage::Assignment: { 8294 case ExpUsage::Assignment: {
8291 auto tableLit = x->new_ptr<TableLit_t>(); 8295 auto tableLit = x->new_ptr<TableLit_t>();
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;
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h
index 24ae490..b68742f 100644
--- a/src/yuescript/yue_parser.h
+++ b/src/yuescript/yue_parser.h
@@ -280,6 +280,8 @@ private:
280 NONE_AST_RULE(fn_arg_def_lit_lines); 280 NONE_AST_RULE(fn_arg_def_lit_lines);
281 NONE_AST_RULE(destruct_def); 281 NONE_AST_RULE(destruct_def);
282 NONE_AST_RULE(macro_args_def); 282 NONE_AST_RULE(macro_args_def);
283 NONE_AST_RULE(var_arg_def);
284 NONE_AST_RULE(outer_var_shadow_def);
283 NONE_AST_RULE(chain_call); 285 NONE_AST_RULE(chain_call);
284 NONE_AST_RULE(chain_call_list); 286 NONE_AST_RULE(chain_call_list);
285 NONE_AST_RULE(chain_index_chain); 287 NONE_AST_RULE(chain_index_chain);