diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/yuescript/yue_ast.cpp | 7 | ||||
| -rw-r--r-- | src/yuescript/yue_ast.h | 19 | ||||
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 32 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.cpp | 11 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.h | 2 |
5 files changed, 46 insertions, 25 deletions
diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp index fdb1d20..e69dd37 100644 --- a/src/yuescript/yue_ast.cpp +++ b/src/yuescript/yue_ast.cpp | |||
| @@ -372,8 +372,8 @@ std::string With_t::to_string(void* ud) const { | |||
| 372 | str_list temp{ | 372 | str_list temp{ |
| 373 | eop ? "with?"s : "with"s, | 373 | eop ? "with?"s : "with"s, |
| 374 | valueList->to_string(ud)}; | 374 | valueList->to_string(ud)}; |
| 375 | if (assigns) { | 375 | if (assign) { |
| 376 | temp.push_back(assigns->to_string(ud)); | 376 | temp.push_back(':' + assign->to_string(ud)); |
| 377 | } | 377 | } |
| 378 | if (body.is<Statement_t>()) { | 378 | if (body.is<Statement_t>()) { |
| 379 | return join(temp, " "sv) + " do "s + body->to_string(ud); | 379 | return join(temp, " "sv) + " do "s + body->to_string(ud); |
| @@ -419,6 +419,9 @@ std::string SwitchCase_t::to_string(void* ud) const { | |||
| 419 | std::string Switch_t::to_string(void* ud) const { | 419 | std::string Switch_t::to_string(void* ud) const { |
| 420 | auto info = reinterpret_cast<YueFormat*>(ud); | 420 | auto info = reinterpret_cast<YueFormat*>(ud); |
| 421 | str_list temp{"switch "s + target->to_string(ud)}; | 421 | str_list temp{"switch "s + target->to_string(ud)}; |
| 422 | if (assignment) { | ||
| 423 | temp.back().append(" :"s + assignment->to_string(ud)); | ||
| 424 | } | ||
| 422 | info->pushScope(); | 425 | info->pushScope(); |
| 423 | for (auto branch : branches.objects()) { | 426 | for (auto branch : branches.objects()) { |
| 424 | temp.emplace_back(info->ind() + branch->to_string(ud)); | 427 | temp.emplace_back(info->ind() + branch->to_string(ud)); |
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index 0c15fac..946a587 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
| @@ -287,9 +287,9 @@ AST_END(Return) | |||
| 287 | AST_NODE(With) | 287 | AST_NODE(With) |
| 288 | ast_ptr<false, ExistentialOp_t> eop; | 288 | ast_ptr<false, ExistentialOp_t> eop; |
| 289 | ast_ptr<true, ExpList_t> valueList; | 289 | ast_ptr<true, ExpList_t> valueList; |
| 290 | ast_ptr<false, Assign_t> assigns; | 290 | ast_ptr<false, Assign_t> assign; |
| 291 | ast_sel<true, Block_t, Statement_t> body; | 291 | ast_sel<true, Block_t, Statement_t> body; |
| 292 | AST_MEMBER(With, &eop, &valueList, &assigns, &body) | 292 | AST_MEMBER(With, &eop, &valueList, &assign, &body) |
| 293 | AST_END(With) | 293 | AST_END(With) |
| 294 | 294 | ||
| 295 | AST_NODE(SwitchList) | 295 | AST_NODE(SwitchList) |
| @@ -304,20 +304,21 @@ AST_NODE(SwitchCase) | |||
| 304 | AST_MEMBER(SwitchCase, &condition, &body) | 304 | AST_MEMBER(SwitchCase, &condition, &body) |
| 305 | AST_END(SwitchCase) | 305 | AST_END(SwitchCase) |
| 306 | 306 | ||
| 307 | AST_NODE(Assignment) | ||
| 308 | ast_ptr<false, ExpList_t> expList; | ||
| 309 | ast_ptr<true, Assign_t> assign; | ||
| 310 | AST_MEMBER(Assignment, &expList, &assign) | ||
| 311 | AST_END(Assignment) | ||
| 312 | |||
| 307 | AST_NODE(Switch) | 313 | AST_NODE(Switch) |
| 308 | ast_ptr<true, Exp_t> target; | 314 | ast_ptr<true, Exp_t> target; |
| 315 | ast_ptr<false, Assignment_t> assignment; | ||
| 309 | ast_ptr<true, Seperator_t> sep; | 316 | ast_ptr<true, Seperator_t> sep; |
| 310 | ast_list<true, SwitchCase_t> branches; | 317 | ast_list<true, SwitchCase_t> branches; |
| 311 | ast_sel<false, Block_t, Statement_t> lastBranch; | 318 | ast_sel<false, Block_t, Statement_t> lastBranch; |
| 312 | AST_MEMBER(Switch, &target, &sep, &branches, &lastBranch) | 319 | AST_MEMBER(Switch, &target, &assignment, &sep, &branches, &lastBranch) |
| 313 | AST_END(Switch) | 320 | AST_END(Switch) |
| 314 | 321 | ||
| 315 | AST_NODE(Assignment) | ||
| 316 | ast_ptr<false, ExpList_t> expList; | ||
| 317 | ast_ptr<true, Assign_t> assign; | ||
| 318 | AST_MEMBER(Assignment, &expList, &assign) | ||
| 319 | AST_END(Assignment) | ||
| 320 | |||
| 321 | AST_NODE(IfCond) | 322 | AST_NODE(IfCond) |
| 322 | ast_ptr<true, Exp_t> condition; | 323 | ast_ptr<true, Exp_t> condition; |
| 323 | ast_ptr<false, Assignment_t> assignment; | 324 | ast_ptr<false, Assignment_t> assignment; |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 7abc929..9d2037f 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
| @@ -78,7 +78,7 @@ static std::unordered_set<std::string> Metamethods = { | |||
| 78 | "close"s // Lua 5.4 | 78 | "close"s // Lua 5.4 |
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | const std::string_view version = "0.28.3"sv; | 81 | const std::string_view version = "0.28.4"sv; |
| 82 | const std::string_view extension = "yue"sv; | 82 | const std::string_view extension = "yue"sv; |
| 83 | 83 | ||
| 84 | class CompileError : public std::logic_error { | 84 | class CompileError : public std::logic_error { |
| @@ -9370,11 +9370,11 @@ private: | |||
| 9370 | std::string withVar; | 9370 | std::string withVar; |
| 9371 | bool needScope = !currentScope().lastStatement && !returnValue; | 9371 | bool needScope = !currentScope().lastStatement && !returnValue; |
| 9372 | bool extraScope = false; | 9372 | bool extraScope = false; |
| 9373 | if (with->assigns) { | 9373 | if (with->assign) { |
| 9374 | auto vars = getAssignVars(with); | 9374 | auto vars = getAssignVars(with); |
| 9375 | if (vars.front().empty() || isDeclaredAsGlobal(vars.front())) { | 9375 | if (vars.front().empty() || isDeclaredAsGlobal(vars.front())) { |
| 9376 | if (with->assigns->values.objects().size() == 1) { | 9376 | if (with->assign->values.objects().size() == 1) { |
| 9377 | auto var = singleVariableFrom(with->assigns->values.objects().front(), AccessType::Read); | 9377 | auto var = singleVariableFrom(with->assign->values.objects().front(), AccessType::Read); |
| 9378 | if (!var.empty() && isLocal(var)) { | 9378 | if (!var.empty() && isLocal(var)) { |
| 9379 | withVar = var; | 9379 | withVar = var; |
| 9380 | } | 9380 | } |
| @@ -9384,7 +9384,7 @@ private: | |||
| 9384 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 9384 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
| 9385 | assignment->expList.set(toAst<ExpList_t>(withVar, x)); | 9385 | assignment->expList.set(toAst<ExpList_t>(withVar, x)); |
| 9386 | auto assign = x->new_ptr<Assign_t>(); | 9386 | auto assign = x->new_ptr<Assign_t>(); |
| 9387 | assign->values.push_back(with->assigns->values.objects().front()); | 9387 | assign->values.push_back(with->assign->values.objects().front()); |
| 9388 | assignment->action.set(assign); | 9388 | assignment->action.set(assign); |
| 9389 | if (needScope) { | 9389 | if (needScope) { |
| 9390 | extraScope = true; | 9390 | extraScope = true; |
| @@ -9398,7 +9398,7 @@ private: | |||
| 9398 | auto assign = x->new_ptr<Assign_t>(); | 9398 | auto assign = x->new_ptr<Assign_t>(); |
| 9399 | assign->values.push_back(toAst<Exp_t>(withVar, x)); | 9399 | assign->values.push_back(toAst<Exp_t>(withVar, x)); |
| 9400 | bool skipFirst = true; | 9400 | bool skipFirst = true; |
| 9401 | for (auto value : with->assigns->values.objects()) { | 9401 | for (auto value : with->assign->values.objects()) { |
| 9402 | if (skipFirst) { | 9402 | if (skipFirst) { |
| 9403 | skipFirst = false; | 9403 | skipFirst = false; |
| 9404 | continue; | 9404 | continue; |
| @@ -9411,7 +9411,7 @@ private: | |||
| 9411 | withVar = vars.front(); | 9411 | withVar = vars.front(); |
| 9412 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 9412 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
| 9413 | assignment->expList.set(with->valueList); | 9413 | assignment->expList.set(with->valueList); |
| 9414 | assignment->action.set(with->assigns); | 9414 | assignment->action.set(with->assign); |
| 9415 | if (needScope) { | 9415 | if (needScope) { |
| 9416 | extraScope = true; | 9416 | extraScope = true; |
| 9417 | temp.push_back(indent() + "do"s + nll(with)); | 9417 | temp.push_back(indent() + "do"s + nll(with)); |
| @@ -10760,10 +10760,26 @@ private: | |||
| 10760 | pushScope(); | 10760 | pushScope(); |
| 10761 | } | 10761 | } |
| 10762 | bool extraScope = false; | 10762 | bool extraScope = false; |
| 10763 | if (switchNode->assignment) { | ||
| 10764 | if (needScope) { | ||
| 10765 | extraScope = true; | ||
| 10766 | temp.push_back(indent() + "do"s + nll(x)); | ||
| 10767 | pushScope(); | ||
| 10768 | } | ||
| 10769 | auto asmt = x->new_ptr<ExpListAssign_t>(); | ||
| 10770 | auto expList = x->new_ptr<ExpList_t>(); | ||
| 10771 | expList->exprs.push_back(switchNode->target); | ||
| 10772 | if (switchNode->assignment->expList) { | ||
| 10773 | expList->exprs.dup(switchNode->assignment->expList->exprs); | ||
| 10774 | } | ||
| 10775 | asmt->expList.set(expList); | ||
| 10776 | asmt->action.set(switchNode->assignment->assign); | ||
| 10777 | transformAssignment(asmt, temp); | ||
| 10778 | } | ||
| 10763 | auto objVar = singleVariableFrom(switchNode->target, AccessType::Read); | 10779 | auto objVar = singleVariableFrom(switchNode->target, AccessType::Read); |
| 10764 | if (objVar.empty() || !isLocal(objVar)) { | 10780 | if (objVar.empty() || !isLocal(objVar)) { |
| 10765 | if (usage == ExpUsage::Common || usage == ExpUsage::Assignment) { | 10781 | if (usage == ExpUsage::Common || usage == ExpUsage::Assignment) { |
| 10766 | if (needScope) { | 10782 | if (needScope && !extraScope) { |
| 10767 | extraScope = true; | 10783 | extraScope = true; |
| 10768 | temp.push_back(indent() + "do"s + nll(x)); | 10784 | temp.push_back(indent() + "do"s + nll(x)); |
| 10769 | pushScope(); | 10785 | pushScope(); |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 078509c..0271e07 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
| @@ -118,8 +118,8 @@ YueParser::YueParser() { | |||
| 118 | return false; | 118 | return false; |
| 119 | }); | 119 | }); |
| 120 | 120 | ||
| 121 | if_assignment_syntax_error = pl::user(true_(), [](const item_t& item) { | 121 | assignment_expression_syntax_error = pl::user(true_(), [](const item_t& item) { |
| 122 | throw ParserError("use := for if-assignment expression"sv, item.begin); | 122 | throw ParserError("use := for assignment expression"sv, item.begin); |
| 123 | return false; | 123 | return false; |
| 124 | }); | 124 | }); |
| 125 | 125 | ||
| @@ -356,7 +356,7 @@ YueParser::YueParser() { | |||
| 356 | 356 | ||
| 357 | Return = key("return") >> -(space >> (TableBlock | ExpListLow)); | 357 | Return = key("return") >> -(space >> (TableBlock | ExpListLow)); |
| 358 | 358 | ||
| 359 | with_exp = ExpList >> -(space >> Assign); | 359 | with_exp = ExpList >> -(space >> (':' >> Assign | and_('=') >> assignment_expression_syntax_error)); |
| 360 | 360 | ||
| 361 | With = key("with") >> -ExistentialOp >> space >> disable_do_chain_arg_table_block_rule(with_exp) >> space >> body_with("do"); | 361 | With = key("with") >> -ExistentialOp >> space >> disable_do_chain_arg_table_block_rule(with_exp) >> space >> body_with("do"); |
| 362 | SwitchCase = key("when") >> space >> disable_chain_rule(disable_arg_table_block_rule(SwitchList)) >> space >> body_with("then"); | 362 | SwitchCase = key("when") >> space >> disable_chain_rule(disable_arg_table_block_rule(SwitchList)) >> space >> body_with("then"); |
| @@ -372,7 +372,8 @@ YueParser::YueParser() { | |||
| 372 | and_(SimpleTable | TableLit) >> Exp | | 372 | and_(SimpleTable | TableLit) >> Exp | |
| 373 | exp_not_tab >> *(space >> ',' >> space >> exp_not_tab) | 373 | exp_not_tab >> *(space >> ',' >> space >> exp_not_tab) |
| 374 | ); | 374 | ); |
| 375 | Switch = key("switch") >> space >> Exp >> | 375 | Switch = key("switch") >> space >> |
| 376 | Exp >> -(space >> Assignment) >> | ||
| 376 | space >> Seperator >> ( | 377 | space >> Seperator >> ( |
| 377 | SwitchCase >> space >> ( | 378 | SwitchCase >> space >> ( |
| 378 | switch_block | | 379 | switch_block | |
| @@ -381,7 +382,7 @@ YueParser::YueParser() { | |||
| 381 | +space_break >> advance_match >> space >> SwitchCase >> switch_block >> pop_indent | 382 | +space_break >> advance_match >> space >> SwitchCase >> switch_block >> pop_indent |
| 382 | ); | 383 | ); |
| 383 | 384 | ||
| 384 | Assignment = -(',' >> space >> ExpList >> space) >> (':' >> Assign | and_('=') >> if_assignment_syntax_error); | 385 | Assignment = -(',' >> space >> ExpList >> space) >> (':' >> Assign | and_('=') >> assignment_expression_syntax_error); |
| 385 | IfCond = disable_chain_rule(disable_arg_table_block_rule(Exp >> -(space >> Assignment))); | 386 | IfCond = disable_chain_rule(disable_arg_table_block_rule(Exp >> -(space >> Assignment))); |
| 386 | if_else_if = -(line_break >> *space_break >> check_indent_match) >> space >> key("elseif") >> space >> IfCond >> space >> body_with("then"); | 387 | if_else_if = -(line_break >> *space_break >> check_indent_match) >> space >> key("elseif") >> space >> IfCond >> space >> body_with("then"); |
| 387 | if_else = -(line_break >> *space_break >> check_indent_match) >> space >> key("else") >> space >> body; | 388 | if_else = -(line_break >> *space_break >> check_indent_match) >> space >> key("else") >> space >> body; |
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index 4488685..6263857 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h | |||
| @@ -156,7 +156,7 @@ private: | |||
| 156 | NONE_AST_RULE(invalid_interpolation_error); | 156 | NONE_AST_RULE(invalid_interpolation_error); |
| 157 | NONE_AST_RULE(confusing_unary_not_error); | 157 | NONE_AST_RULE(confusing_unary_not_error); |
| 158 | NONE_AST_RULE(table_key_pair_error); | 158 | NONE_AST_RULE(table_key_pair_error); |
| 159 | NONE_AST_RULE(if_assignment_syntax_error); | 159 | NONE_AST_RULE(assignment_expression_syntax_error); |
| 160 | 160 | ||
| 161 | NONE_AST_RULE(inc_exp_level); | 161 | NONE_AST_RULE(inc_exp_level); |
| 162 | NONE_AST_RULE(dec_exp_level); | 162 | NONE_AST_RULE(dec_exp_level); |
