From ccfe66f87663e10603e453f02894bb82dd23c93b Mon Sep 17 00:00:00 2001 From: Li Jin Date: Mon, 19 Jan 2026 17:11:31 +0800 Subject: Made `;` work as statements separator. --- src/yue.cpp | 2 +- src/yuescript/yue_ast.cpp | 7 --- src/yuescript/yue_ast.h | 16 ++--- src/yuescript/yue_compiler.cpp | 137 +++++++++++++---------------------------- src/yuescript/yue_parser.cpp | 35 ++++++----- src/yuescript/yue_parser.h | 2 +- 6 files changed, 71 insertions(+), 128 deletions(-) (limited to 'src') diff --git a/src/yue.cpp b/src/yue.cpp index b93f75e..2722c55 100644 --- a/src/yue.cpp +++ b/src/yue.cpp @@ -341,7 +341,7 @@ int main(int narg, const char** args) { " -- Read from standard in, print to standard out\n" " (Must be first and only argument)\n\n" " --target=version Specify the Lua version that codes will be generated to\n" - " (version can only be 5.1, 5.2, 5.3 or 5.4)\n" + " (version can only be 5.1 to 5.5)\n" " --path=path_str Append an extra Lua search path string to package.path\n\n" " Execute without options to enter REPL, type symbol '$'\n" " in a single line to start/stop multi-line mode\n" diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp index c9fd23f..bcea4d5 100644 --- a/src/yuescript/yue_ast.cpp +++ b/src/yuescript/yue_ast.cpp @@ -370,13 +370,6 @@ std::string PipeBody_t::to_string(void* ud) const { } return join(temp, "\n"sv); } -std::string ExpListLow_t::to_string(void* ud) const { - str_list temp; - for (auto exp : exprs.objects()) { - temp.emplace_back(exp->to_string(ud)); - } - return join(temp, "; "sv); -} std::string ExpList_t::to_string(void* ud) const { str_list temp; for (auto exp : exprs.objects()) { diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index af2355a..5043526 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h @@ -50,7 +50,7 @@ std::string_view ast_name() { return {}; } // clang-format off namespace yue { -class ExpListLow_t; +class ExpList_t; class TableBlock_t; class SimpleTable_t; class TableLit_t; @@ -156,7 +156,7 @@ AST_END(NameList) AST_NODE(LocalValues) ast_ptr nameList; - ast_sel valueList; + ast_sel valueList; AST_MEMBER(LocalValues, &nameList, &valueList) AST_END(LocalValues) @@ -273,12 +273,6 @@ AST_NODE(Backcall) AST_MEMBER(Backcall, &argsDef, &arrow, &value) AST_END(Backcall) -AST_NODE(ExpListLow) - ast_ptr sep; - ast_list exprs; - AST_MEMBER(ExpListLow, &sep, &exprs) -AST_END(ExpListLow) - AST_NODE(ExpList) ast_ptr sep; ast_list exprs; @@ -290,7 +284,7 @@ AST_END(ExpList) AST_NODE(Return) bool allowBlockMacroReturn = false; bool explicitReturn = true; - ast_sel valueList; + ast_sel valueList; AST_MEMBER(Return, &valueList) AST_END(Return) @@ -764,7 +758,7 @@ AST_END(ClassDecl) AST_NODE(GlobalValues) ast_ptr nameList; - ast_sel valueList; + ast_sel valueList; AST_MEMBER(GlobalValues, &nameList, &valueList) AST_END(GlobalValues) @@ -819,7 +813,7 @@ AST_END(FnArrow) AST_NODE(FunLit) ast_ptr argsDef; - ast_sel defaultReturn; + ast_sel defaultReturn; ast_ptr arrow; ast_ptr body; bool noRecursion = false; diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index a2d49af..c7802b6 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp @@ -78,7 +78,7 @@ static std::unordered_set Metamethods = { "close"s // Lua 5.4 }; -const std::string_view version = "0.31.1"sv; +const std::string_view version = "0.32.0"sv; const std::string_view extension = "yue"sv; class CompileError : public std::logic_error { @@ -1057,13 +1057,6 @@ private: } break; } - case id(): { - auto expList = static_cast(item); - if (expList->exprs.size() == 1) { - exp = static_cast(expList->exprs.front()); - } - break; - } case id(): { auto expList = static_cast(item); if (expList->exprs.size() == 1) { @@ -1092,12 +1085,12 @@ private: return nullptr; } - Value_t* singleValueFrom(ast_node* item) const { + Value_t* singleValueFrom(ast_node* item, bool forceUnparened = false) const { if (auto unary = singleUnaryExpFrom(item)) { if (unary->ops.empty()) { Value_t* value = static_cast(unary->expos.back()); if (auto chain = ast_cast(value->item); chain && chain->items.size() == 1) { - if (auto parens = chain->get_by_path(); parens && parens->extra) { + if (auto parens = chain->get_by_path(); parens && (forceUnparened || parens->extra)) { if (auto insideValue = singleValueFrom(parens->expr)) { return insideValue; } @@ -1157,6 +1150,22 @@ private: return exp; } + ast_ptr newReturn(Exp_t* value) { + auto returnNode = value->new_ptr(); + returnNode->explicitReturn = false; + auto expList = value->new_ptr(); + expList->exprs.push_back(value); + returnNode->valueList.set(expList); + return returnNode; + } + + ast_ptr newReturn(ExpList_t* valueList) { + auto returnNode = valueList->new_ptr(); + returnNode->explicitReturn = false; + returnNode->valueList.set(valueList); + return returnNode; + } + SimpleValue_t* simpleSingleValueFrom(ast_node* node) const { auto value = singleValueFrom(node); if (value && value->item.is()) { @@ -1264,7 +1273,7 @@ private: } case id(): { if (auto localValues = static_cast(stmt->content.get())->item.as()) { - if (auto expList = localValues->valueList.as()) { + if (auto expList = localValues->valueList.as()) { return static_cast(expList->exprs.back()); } } @@ -1272,7 +1281,7 @@ private: } case id(): { if (auto globalValues = static_cast(stmt->content.get())->item.as()) { - if (auto expList = globalValues->valueList.as()) { + if (auto expList = globalValues->valueList.as()) { return static_cast(expList->exprs.back()); } } @@ -3717,7 +3726,7 @@ private: bool oneLined = defs.size() == expList->exprs.objects().size(); bool nonRecursionFunLit = false; for (auto val : assign->values.objects()) { - if (auto value = singleValueFrom(val)) { + if (auto value = singleValueFrom(val, true)) { if (auto spValue = value->item.as()) { if (auto funLit = spValue->value.as()) { if (funLit->noRecursion) { @@ -3981,14 +3990,6 @@ private: out.push_back(join(temp, ", "sv)); } - void transformExpListLow(ExpListLow_t* expListLow, str_list& out) { - str_list temp; - for (auto exp : expListLow->exprs.objects()) { - transformExp(static_cast(exp), temp, ExpUsage::Closure); - } - out.push_back(join(temp, ", "sv)); - } - void transform_pipe_exp(const node_container& values, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { if (values.size() == 1 && usage == ExpUsage::Closure) { transformUnaryExp(static_cast(values.front()), out, ExpUsage::Closure); @@ -4060,11 +4061,7 @@ private: return; } case ExpUsage::Return: { - auto ret = x->new_ptr(); - ret->explicitReturn = false; - auto expListLow = x->new_ptr(); - expListLow->exprs.push_back(arg); - ret->valueList.set(expListLow); + auto ret = newReturn(arg); transformReturn(ret, out); return; } @@ -4289,11 +4286,7 @@ private: break; } case ExpUsage::Return: { - auto expListLow = exp->new_ptr(); - expListLow->exprs.push_back(e); - auto returnNode = exp->new_ptr(); - returnNode->explicitReturn = false; - returnNode->valueList.set(expListLow); + auto returnNode = newReturn(e); transformReturn(returnNode, out); break; } @@ -4470,11 +4463,7 @@ private: return getUpValueFuncFromBlock(block, ensureArgListInTheEnd, false, blockRewrite); } } - auto returnNode = exp->new_ptr(); - returnNode->explicitReturn = false; - auto returnList = exp->new_ptr(); - returnList->exprs.push_back(exp); - returnNode->valueList.set(returnList); + auto returnNode = newReturn(exp); auto stmt = exp->new_ptr(); stmt->content.set(returnNode); block->statementOrComments.push_back(stmt); @@ -4561,12 +4550,8 @@ private: _buf << indent(1) << "return "s << objVar << nl(x); _buf << indent() << "else"s << nl(x); temp.push_back(clearBuf()); - auto ret = x->new_ptr(); - ret->explicitReturn = false; - auto retList = x->new_ptr(); - retList->exprs.push_back(exp->nilCoalesed); - ret->valueList.set(retList); incIndentOffset(); + auto ret = newReturn(exp->nilCoalesed); transformReturn(ret, temp); decIndentOffset(); temp.push_back(indent() + "end"s + nl(x)); @@ -4727,10 +4712,8 @@ private: default: YUEE("AST node mismatch", content); break; } } - if (funLit->defaultReturn.is()) { - auto returnNode = newBlock->new_ptr(); - returnNode->explicitReturn = false; - returnNode->valueList.set(funLit->defaultReturn); + if (auto defaultReturn = funLit->defaultReturn.as()) { + auto returnNode = newReturn(defaultReturn); auto stmt = newBlock->new_ptr(); stmt->content.set(returnNode); newBlock->statementOrComments.push_back(stmt); @@ -5264,11 +5247,9 @@ private: auto expList = expListFrom(last); BREAK_IF(!expList); BREAK_IF(last->appendix && !last->appendix->item.is()); - auto expListLow = x->new_ptr(); - expListLow->exprs.dup(expList->exprs); auto returnNode = x->new_ptr(); returnNode->explicitReturn = false; - returnNode->valueList.set(expListLow); + returnNode->valueList.set(expList); returnNode->allowBlockMacroReturn = true; last->content.set(returnNode); BLOCK_END @@ -5713,7 +5694,7 @@ private: if (!target) target = returnNode; throw CompileError("explicit return statement is not allowed in this context"sv, target); } - if (auto valueList = returnNode->valueList.as()) { + if (auto valueList = returnNode->valueList.as()) { if (valueList->exprs.size() == 1) { auto exp = static_cast(valueList->exprs.back()); if (isPurePipeChain(exp)) { @@ -5783,7 +5764,7 @@ private: return; } else { str_list temp; - transformExpListLow(valueList, temp); + transformExpList(valueList, temp); out.push_back(indent() + "return "s + temp.back() + nl(returnNode)); } } else if (auto tableBlock = returnNode->valueList.as()) { @@ -6250,11 +6231,7 @@ private: case ExpUsage::Return: case ExpUsage::Closure: { auto exp = newExp(partTwo, x); - auto ret = x->new_ptr(); - ret->explicitReturn = false; - auto expListLow = x->new_ptr(); - expListLow->exprs.push_back(exp); - ret->valueList.set(expListLow); + auto ret = newReturn(exp); transformReturn(ret, temp); break; } @@ -6349,11 +6326,7 @@ private: switch (usage) { case ExpUsage::Closure: case ExpUsage::Return: { - auto returnNode = x->new_ptr(); - returnNode->explicitReturn = false; - auto expListLow = x->new_ptr(); - expListLow->exprs.push_back(funLit); - returnNode->valueList.set(expListLow); + auto returnNode = newReturn(funLit); transformReturn(returnNode, temp); break; } @@ -6484,11 +6457,7 @@ private: } switch (usage) { case ExpUsage::Closure: { - auto returnNode = x->new_ptr(); - returnNode->explicitReturn = false; - auto values = x->new_ptr(); - values->exprs.push_back(newChainExp); - returnNode->valueList.set(values); + auto returnNode = newReturn(newChainExp); transformReturn(returnNode, temp); popScope(); *funcStart = anonFuncStart() + nl(x); @@ -6498,11 +6467,7 @@ private: break; } case ExpUsage::Return: { - auto returnNode = x->new_ptr(); - returnNode->explicitReturn = false; - auto values = x->new_ptr(); - values->exprs.push_back(newChainExp); - returnNode->valueList.set(values); + auto returnNode = newReturn(newChainExp); transformReturn(returnNode, temp); break; } @@ -7361,11 +7326,7 @@ private: break; } case ExpUsage::Return: { - auto expListLow = x->new_ptr(); - expListLow->exprs.push_back(node); - auto returnNode = x->new_ptr(); - returnNode->explicitReturn = false; - returnNode->valueList.set(expListLow); + auto returnNode = newReturn(node.to()); transformReturn(returnNode, out); break; } @@ -8377,11 +8338,7 @@ private: auto simpleValue = x->new_ptr(); simpleValue->value.set(tableLit); auto exp = newExp(simpleValue, x); - auto returnNode = x->new_ptr(); - returnNode->explicitReturn = false; - auto expList = x->new_ptr(); - expList->exprs.push_back(exp); - returnNode->valueList.set(expList); + auto returnNode = newReturn(exp); transformReturn(returnNode, out); break; } @@ -9190,10 +9147,7 @@ private: } } else { auto accum = transformForNumInner(forNum, temp); - auto returnNode = x->new_ptr(); - returnNode->explicitReturn = false; - auto expListLow = toAst(accum, x); - returnNode->valueList.set(expListLow); + auto returnNode = newReturn(toAst(accum, forNum)); transformReturn(returnNode, temp); } out.push_back(join(temp)); @@ -9304,10 +9258,7 @@ private: } } else { auto accum = transformForEachInner(forEach, temp); - auto returnNode = x->new_ptr(); - returnNode->explicitReturn = false; - auto expListLow = toAst(accum, x); - returnNode->valueList.set(expListLow); + auto returnNode = newReturn(toAst(accum, forEach)); transformReturn(returnNode, temp); } out.push_back(join(temp)); @@ -10393,8 +10344,8 @@ private: auto assignment = x->new_ptr(); assignment->expList.set(expList); auto assign = x->new_ptr(); - if (auto expListLow = values->valueList.as()) { - assign->values.dup(expListLow->exprs); + if (auto expList = values->valueList.as()) { + assign->values.dup(expList->exprs); } else { auto tableBlock = values->valueList.to(); assign->values.push_back(tableBlock); @@ -11897,8 +11848,8 @@ private: auto assignment = x->new_ptr(); assignment->expList.set(expList); auto assign = x->new_ptr(); - if (auto expListLow = values->valueList.as()) { - assign->values.dup(expListLow->exprs); + if (auto expList = values->valueList.as()) { + assign->values.dup(expList->exprs); } else { auto tableBlock = values->valueList.to(); assign->values.push_back(tableBlock); @@ -11906,7 +11857,7 @@ private: assignment->action.set(assign); bool oneLined = transformAssignment(assignment, temp); for (auto val : assign->values.objects()) { - if (auto value = singleValueFrom(val)) { + if (auto value = singleValueFrom(val, true)) { if (auto spValue = value->item.as()) { if (auto funLit = spValue->value.as()) { if (!funLit->noRecursion) { diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index ab1ba7a..b032826 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp @@ -393,7 +393,7 @@ YueParser::YueParser() { in_block = space_break >> *(*set(" \t") >> line_break) >> advance_match >> ensure(Block, pop_indent); LocalFlag = expr('*') | '^'; - LocalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow | expected_expression_error)); + LocalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpList | expected_expression_error)); Local = key("local") >> space >> (LocalFlag | LocalValues | invalid_local_declaration_error); ConstAttrib = key("const"); @@ -478,7 +478,7 @@ YueParser::YueParser() { Continue = key("continue"); BreakLoop = (Break >> -(space >> Exp) | Continue) >> not_alpha_num; - Return = key("return") >> -(space >> (TableBlock | ExpListLow)); + Return = key("return") >> -(space >> (TableBlock | ExpList)); must_exp = Exp | expected_expression_error; @@ -674,7 +674,7 @@ YueParser::YueParser() { Assign = '=' >> space >> Seperator >> ( With | If | Switch | TableBlock | - (SpreadListExp | Exp) >> *(space >> set(",;") >> space >> (SpreadListExp | Exp)) | + (SpreadListExp | Exp) >> *(space >> set(",") >> space >> (SpreadListExp | Exp)) | expected_expression_error ); @@ -927,7 +927,7 @@ YueParser::YueParser() { -(space >> key("using") >> prevent_indent >> space >> ensure(ExpList | expected_expression_error, pop_indent)) ) >> -ClassBlock; - GlobalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow | expected_expression_error)); + GlobalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpList | expected_expression_error)); GlobalOp = expr('*') | '^'; Global = key("global") >> space >> ( -(ConstAttrib >> space) >> ClassDecl | @@ -1056,7 +1056,7 @@ YueParser::YueParser() { return st->fnArrowAvailable; }) >> -(FnArgsDef >> -(':' >> space >> - disable_fun_lit >> ensure(ExpListLow | DefaultValue, enable_fun_lit) + disable_fun_lit >> ensure(ExpList | DefaultValue, enable_fun_lit) ) ) >> space >> FnArrow >> -(space >> Body); @@ -1087,7 +1087,6 @@ YueParser::YueParser() { *(+space_break >> check_indent_match >> space >> pipe_operator >> space >> must_unary_exp); ExpList = Seperator >> Exp >> *(space >> ',' >> space >> Exp); - ExpListLow = Seperator >> Exp >> *(space >> set(",;") >> space >> Exp); arg_line = check_indent_match >> space >> Exp >> *(space >> ',' >> space >> Exp); arg_block = arg_line >> *(space >> ',' >> space_break >> arg_line) >> pop_indent; @@ -1124,17 +1123,18 @@ YueParser::YueParser() { ChainAssign = Seperator >> Exp >> +(space >> '=' >> space >> Exp >> space >> and_('=')) >> space >> Assign; - StatementAppendix = (IfLine | WhileLine | CompFor) >> space; - Statement = + StatementAppendix = IfLine | WhileLine | CompFor; + Statement = ( ( Import | Export | Global | Macro | MacroInPlace | Label - ) >> space | ( + ) | ( Local | While | Repeat | For | Return | BreakLoop | Goto | ShortTabAppending | LocalAttrib | Backcall | PipeBody | ExpListAssign | ChainAssign | StatementAppendix >> empty_block_error | and_(key("else") | key("elseif") | key("when")) >> dangling_clause_error - ) >> space >> -StatementAppendix; + ) >> space >> -StatementAppendix + ) >> space; StatementSep = white >> (set("('\"") | "[[" | "[="); @@ -1158,15 +1158,20 @@ YueParser::YueParser() { return false; }); + is_lax = pl::user(true_(), [](const item_t& item) { + State* st = reinterpret_cast(item.user_data); + return st->lax; + }); + line = *(EmptyLine >> line_break) >> ( - check_indent_match >> space >> Statement | + check_indent_match >> space >> Statement >> *(';' >> -(space >> Statement)) | YueComment | advance_match >> ensure(space >> (indentation_error | Statement), pop_indent) ); - Block = Seperator >> (pl::user(true_(), [](const item_t& item) { - State* st = reinterpret_cast(item.user_data); - return st->lax; - }) >> lax_line >> *(line_break >> lax_line) | line >> *(line_break >> line)); + Block = Seperator >> ( + is_lax >> lax_line >> *(line_break >> lax_line) | + line >> *(line_break >> line) + ); shebang = "#!" >> *(not_(stop) >> any_char); BlockEnd = Block >> plain_white >> stop; diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index c516ccd..df9f39c 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h @@ -319,6 +319,7 @@ private: NONE_AST_RULE(yue_multiline_comment); NONE_AST_RULE(line); NONE_AST_RULE(shebang); + NONE_AST_RULE(is_lax); NONE_AST_RULE(lax_line); AST_RULE(Num); @@ -361,7 +362,6 @@ private: AST_RULE(Backcall); AST_RULE(SubBackcall); AST_RULE(PipeBody); - AST_RULE(ExpListLow); AST_RULE(ExpList); AST_RULE(Return); AST_RULE(With); -- cgit v1.2.3-55-g6feb