From 514b9f97febe8920a78d6078b092fe84b859a963 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Thu, 7 Dec 2023 23:49:48 +0800 Subject: changed the if-assignment syntax to prevent some errors. --- src/yuescript/yue_ast.h | 7 ++++--- src/yuescript/yue_compiler.cpp | 23 +++++++++++++---------- src/yuescript/yue_parser.cpp | 9 +++++++-- src/yuescript/yue_parser.h | 1 + 4 files changed, 25 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index fa47559..6b2b7f8 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h @@ -302,14 +302,15 @@ AST_NODE(Switch) AST_END(Switch, "switch"sv) AST_NODE(Assignment) - ast_ptr expList; + ast_ptr expList; ast_ptr assign; AST_MEMBER(Assignment, &expList, &assign) AST_END(Assignment, "assignment"sv) AST_NODE(IfCond) - ast_sel condition; - AST_MEMBER(IfCond, &condition) + ast_ptr condition; + ast_ptr assignment; + AST_MEMBER(IfCond, &condition, &assignment) AST_END(IfCond, "if_cond"sv) AST_LEAF(IfType) diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 69a028f..d37f911 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp @@ -75,7 +75,7 @@ static std::unordered_set Metamethods = { "close"s // Lua 5.4 }; -const std::string_view version = "0.20.7"sv; +const std::string_view version = "0.21.0"sv; const std::string_view extension = "yue"sv; class CompileError : public std::logic_error { @@ -3088,7 +3088,7 @@ private: for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) { ns.push_back(*it); if (auto cond = ast_cast(*it)) { - if (*it != nodes.front() && cond->condition.is()) { + if (*it != nodes.front() && cond->assignment) { auto x = *it; auto newIf = x->new_ptr(); newIf->type.set(toAst("if"sv, x)); @@ -3142,11 +3142,12 @@ private: default: YUEE("AST node mismatch", node); break; } } - auto asmt = ifCondPairs.front().first->condition.as(); + auto firstIfCond = ifCondPairs.front().first; + auto asmt = firstIfCond->assignment.get(); bool storingValue = false; ast_ptr extraAssignment; if (asmt) { - ast_ptr exp = asmt->expList->exprs.front(); + auto exp = firstIfCond->condition.get(); auto x = exp; auto var = singleVariableFrom(exp, false); if (var.empty() || isGlobal(var)) { @@ -3164,11 +3165,12 @@ private: temp.push_back(indent() + "do"s + nll(asmt)); pushScope(); } - asmt->expList->exprs.pop_front(); auto expList = toAst(desVar, x); auto assignment = x->new_ptr(); - for (auto expr : asmt->expList->exprs.objects()) { - expList->exprs.push_back(expr); + if (asmt->expList) { + for (auto expr : asmt->expList->exprs.objects()) { + expList->exprs.push_back(expr); + } } assignment->expList.set(expList); assignment->action.set(asmt->assign); @@ -3196,9 +3198,10 @@ private: } auto expList = x->new_ptr(); expList->exprs.push_back(exp); - asmt->expList->exprs.pop_front(); - for (auto expr : asmt->expList->exprs.objects()) { - expList->exprs.push_back(expr); + if (asmt->expList) { + for (auto expr : asmt->expList->exprs.objects()) { + expList->exprs.push_back(expr); + } } auto assignment = x->new_ptr(); assignment->expList.set(expList); diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 2206686..5b97a25 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp @@ -114,6 +114,11 @@ YueParser::YueParser() { return false; }); + if_assignment_syntax_error = pl::user(true_(), [](const item_t& item) { + throw ParserError("use := for if-assignment expression"sv, item.begin); + return false; + }); + #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> cut) #define key(str) (expr(str) >> not_alpha_num) @@ -369,8 +374,8 @@ YueParser::YueParser() { +space_break >> advance_match >> space >> SwitchCase >> switch_block >> pop_indent ) >> switch_block; - Assignment = ExpList >> space >> Assign; - IfCond = disable_chain_rule(disable_arg_table_block_rule(Assignment | Exp)); + Assignment = -(',' >> space >> ExpList >> space) >> (':' >> Assign | and_('=') >> if_assignment_syntax_error); + IfCond = disable_chain_rule(disable_arg_table_block_rule(Exp >> -(space >> Assignment))); if_else_if = -(line_break >> *space_break >> check_indent_match) >> space >> key("elseif") >> space >> IfCond >> space >> body_with("then"); if_else = -(line_break >> *space_break >> check_indent_match) >> space >> key("else") >> space >> body; IfType = (expr("if") | "unless") >> not_alpha_num; diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index 16b57b2..c3d5d7d 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h @@ -141,6 +141,7 @@ private: NONE_AST_RULE(invalid_interpolation_error); NONE_AST_RULE(confusing_unary_not_error); NONE_AST_RULE(table_key_pair_error); + NONE_AST_RULE(if_assignment_syntax_error); NONE_AST_RULE(inc_exp_level); NONE_AST_RULE(dec_exp_level); -- cgit v1.2.3-55-g6feb