diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 78 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.cpp | 2 | ||||
| -rw-r--r-- | src/yuescript/yuescript.h | 8 |
3 files changed, 55 insertions, 33 deletions
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index e7fe0c0..3d98fbc 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
| @@ -75,7 +75,7 @@ static std::unordered_set<std::string> Metamethods = { | |||
| 75 | "close"s // Lua 5.4 | 75 | "close"s // Lua 5.4 |
| 76 | }; | 76 | }; |
| 77 | 77 | ||
| 78 | const std::string_view version = "0.27.0"sv; | 78 | const std::string_view version = "0.27.1"sv; |
| 79 | const std::string_view extension = "yue"sv; | 79 | const std::string_view extension = "yue"sv; |
| 80 | 80 | ||
| 81 | class CompileError : public std::logic_error { | 81 | class CompileError : public std::logic_error { |
| @@ -1486,7 +1486,7 @@ private: | |||
| 1486 | } | 1486 | } |
| 1487 | } | 1487 | } |
| 1488 | 1488 | ||
| 1489 | bool isPureBackcall(Exp_t* exp) const { | 1489 | bool isPurePipeChain(Exp_t* exp) const { |
| 1490 | return exp->opValues.empty() && exp->pipeExprs.size() > 1; | 1490 | return exp->opValues.empty() && exp->pipeExprs.size() > 1; |
| 1491 | } | 1491 | } |
| 1492 | 1492 | ||
| @@ -1869,7 +1869,7 @@ private: | |||
| 1869 | } | 1869 | } |
| 1870 | } else if (expList->exprs.size() == 1) { | 1870 | } else if (expList->exprs.size() == 1) { |
| 1871 | auto exp = static_cast<Exp_t*>(expList->exprs.back()); | 1871 | auto exp = static_cast<Exp_t*>(expList->exprs.back()); |
| 1872 | if (isPureBackcall(exp)) { | 1872 | if (isPurePipeChain(exp)) { |
| 1873 | transformExp(exp, out, ExpUsage::Common); | 1873 | transformExp(exp, out, ExpUsage::Common); |
| 1874 | break; | 1874 | break; |
| 1875 | } | 1875 | } |
| @@ -2061,7 +2061,7 @@ private: | |||
| 2061 | } | 2061 | } |
| 2062 | } | 2062 | } |
| 2063 | 2063 | ||
| 2064 | void transformAssignment(ExpListAssign_t* assignment, str_list& out, bool optionalDestruct = false) { | 2064 | bool transformAssignment(ExpListAssign_t* assignment, str_list& out, bool optionalDestruct = false) { |
| 2065 | checkAssignable(assignment->expList); | 2065 | checkAssignable(assignment->expList); |
| 2066 | BLOCK_START | 2066 | BLOCK_START |
| 2067 | auto assign = ast_cast<Assign_t>(assignment->action); | 2067 | auto assign = ast_cast<Assign_t>(assignment->action); |
| @@ -2176,7 +2176,7 @@ private: | |||
| 2176 | temp.push_back(indent() + "end"s + nll(assignment)); | 2176 | temp.push_back(indent() + "end"s + nll(assignment)); |
| 2177 | } | 2177 | } |
| 2178 | out.push_back(join(temp)); | 2178 | out.push_back(join(temp)); |
| 2179 | return; | 2179 | return false; |
| 2180 | BLOCK_END | 2180 | BLOCK_END |
| 2181 | } | 2181 | } |
| 2182 | { | 2182 | { |
| @@ -2248,7 +2248,7 @@ private: | |||
| 2248 | transformAssignment(afterAssignment, temp); | 2248 | transformAssignment(afterAssignment, temp); |
| 2249 | } | 2249 | } |
| 2250 | out.push_back(join(temp)); | 2250 | out.push_back(join(temp)); |
| 2251 | return; | 2251 | return false; |
| 2252 | } else if (ast_is<TableAppendingOp_t>(chainValue->items.back())) { | 2252 | } else if (ast_is<TableAppendingOp_t>(chainValue->items.back())) { |
| 2253 | str_list temp; | 2253 | str_list temp; |
| 2254 | auto [beforeAssignment, afterAssignment] = splitAssignment(); | 2254 | auto [beforeAssignment, afterAssignment] = splitAssignment(); |
| @@ -2300,7 +2300,7 @@ private: | |||
| 2300 | transformAssignment(afterAssignment, temp); | 2300 | transformAssignment(afterAssignment, temp); |
| 2301 | } | 2301 | } |
| 2302 | out.push_back(join(temp)); | 2302 | out.push_back(join(temp)); |
| 2303 | return; | 2303 | return false; |
| 2304 | } else { | 2304 | } else { |
| 2305 | break; | 2305 | break; |
| 2306 | } | 2306 | } |
| @@ -2322,7 +2322,7 @@ private: | |||
| 2322 | std::string preDefine = getPreDefineLine(assignment); | 2322 | std::string preDefine = getPreDefineLine(assignment); |
| 2323 | transformIf(ifNode, out, ExpUsage::Assignment, assignList); | 2323 | transformIf(ifNode, out, ExpUsage::Assignment, assignList); |
| 2324 | out.back().insert(0, preDefine); | 2324 | out.back().insert(0, preDefine); |
| 2325 | return; | 2325 | return false; |
| 2326 | } | 2326 | } |
| 2327 | case id<Switch_t>(): { | 2327 | case id<Switch_t>(): { |
| 2328 | auto switchNode = static_cast<Switch_t*>(value); | 2328 | auto switchNode = static_cast<Switch_t*>(value); |
| @@ -2330,7 +2330,7 @@ private: | |||
| 2330 | std::string preDefine = getPreDefineLine(assignment); | 2330 | std::string preDefine = getPreDefineLine(assignment); |
| 2331 | transformSwitch(switchNode, out, ExpUsage::Assignment, assignList); | 2331 | transformSwitch(switchNode, out, ExpUsage::Assignment, assignList); |
| 2332 | out.back().insert(0, preDefine); | 2332 | out.back().insert(0, preDefine); |
| 2333 | return; | 2333 | return false; |
| 2334 | } | 2334 | } |
| 2335 | case id<With_t>(): { | 2335 | case id<With_t>(): { |
| 2336 | auto withNode = static_cast<With_t*>(value); | 2336 | auto withNode = static_cast<With_t*>(value); |
| @@ -2338,7 +2338,7 @@ private: | |||
| 2338 | std::string preDefine = getPreDefineLine(assignment); | 2338 | std::string preDefine = getPreDefineLine(assignment); |
| 2339 | transformWith(withNode, out, expList); | 2339 | transformWith(withNode, out, expList); |
| 2340 | out.back().insert(0, preDefine); | 2340 | out.back().insert(0, preDefine); |
| 2341 | return; | 2341 | return false; |
| 2342 | } | 2342 | } |
| 2343 | case id<Do_t>(): { | 2343 | case id<Do_t>(): { |
| 2344 | auto expList = assignment->expList.get(); | 2344 | auto expList = assignment->expList.get(); |
| @@ -2346,7 +2346,7 @@ private: | |||
| 2346 | std::string preDefine = getPreDefineLine(assignment); | 2346 | std::string preDefine = getPreDefineLine(assignment); |
| 2347 | transformDo(doNode, out, ExpUsage::Assignment, expList); | 2347 | transformDo(doNode, out, ExpUsage::Assignment, expList); |
| 2348 | out.back().insert(0, preDefine); | 2348 | out.back().insert(0, preDefine); |
| 2349 | return; | 2349 | return false; |
| 2350 | } | 2350 | } |
| 2351 | case id<Comprehension_t>(): { | 2351 | case id<Comprehension_t>(): { |
| 2352 | auto comp = static_cast<Comprehension_t*>(value); | 2352 | auto comp = static_cast<Comprehension_t*>(value); |
| @@ -2358,42 +2358,42 @@ private: | |||
| 2358 | } else { | 2358 | } else { |
| 2359 | transformComprehension(comp, out, ExpUsage::Assignment, expList); | 2359 | transformComprehension(comp, out, ExpUsage::Assignment, expList); |
| 2360 | } | 2360 | } |
| 2361 | return; | 2361 | return false; |
| 2362 | } | 2362 | } |
| 2363 | case id<TblComprehension_t>(): { | 2363 | case id<TblComprehension_t>(): { |
| 2364 | auto expList = assignment->expList.get(); | 2364 | auto expList = assignment->expList.get(); |
| 2365 | std::string preDefine = getPreDefineLine(assignment); | 2365 | std::string preDefine = getPreDefineLine(assignment); |
| 2366 | transformTblComprehension(static_cast<TblComprehension_t*>(value), out, ExpUsage::Assignment, expList); | 2366 | transformTblComprehension(static_cast<TblComprehension_t*>(value), out, ExpUsage::Assignment, expList); |
| 2367 | out.back().insert(0, preDefine); | 2367 | out.back().insert(0, preDefine); |
| 2368 | return; | 2368 | return false; |
| 2369 | } | 2369 | } |
| 2370 | case id<For_t>(): { | 2370 | case id<For_t>(): { |
| 2371 | auto expList = assignment->expList.get(); | 2371 | auto expList = assignment->expList.get(); |
| 2372 | std::string preDefine = getPreDefineLine(assignment); | 2372 | std::string preDefine = getPreDefineLine(assignment); |
| 2373 | transformForInPlace(static_cast<For_t*>(value), out, expList); | 2373 | transformForInPlace(static_cast<For_t*>(value), out, expList); |
| 2374 | out.back().insert(0, preDefine); | 2374 | out.back().insert(0, preDefine); |
| 2375 | return; | 2375 | return false; |
| 2376 | } | 2376 | } |
| 2377 | case id<ForEach_t>(): { | 2377 | case id<ForEach_t>(): { |
| 2378 | auto expList = assignment->expList.get(); | 2378 | auto expList = assignment->expList.get(); |
| 2379 | std::string preDefine = getPreDefineLine(assignment); | 2379 | std::string preDefine = getPreDefineLine(assignment); |
| 2380 | transformForEachInPlace(static_cast<ForEach_t*>(value), out, expList); | 2380 | transformForEachInPlace(static_cast<ForEach_t*>(value), out, expList); |
| 2381 | out.back().insert(0, preDefine); | 2381 | out.back().insert(0, preDefine); |
| 2382 | return; | 2382 | return false; |
| 2383 | } | 2383 | } |
| 2384 | case id<ClassDecl_t>(): { | 2384 | case id<ClassDecl_t>(): { |
| 2385 | auto expList = assignment->expList.get(); | 2385 | auto expList = assignment->expList.get(); |
| 2386 | std::string preDefine = getPreDefineLine(assignment); | 2386 | std::string preDefine = getPreDefineLine(assignment); |
| 2387 | transformClassDecl(static_cast<ClassDecl_t*>(value), out, ExpUsage::Assignment, expList); | 2387 | transformClassDecl(static_cast<ClassDecl_t*>(value), out, ExpUsage::Assignment, expList); |
| 2388 | out.back().insert(0, preDefine); | 2388 | out.back().insert(0, preDefine); |
| 2389 | return; | 2389 | return false; |
| 2390 | } | 2390 | } |
| 2391 | case id<While_t>(): { | 2391 | case id<While_t>(): { |
| 2392 | auto expList = assignment->expList.get(); | 2392 | auto expList = assignment->expList.get(); |
| 2393 | std::string preDefine = getPreDefineLine(assignment); | 2393 | std::string preDefine = getPreDefineLine(assignment); |
| 2394 | transformWhileInPlace(static_cast<While_t*>(value), out, expList); | 2394 | transformWhileInPlace(static_cast<While_t*>(value), out, expList); |
| 2395 | out.back().insert(0, preDefine); | 2395 | out.back().insert(0, preDefine); |
| 2396 | return; | 2396 | return false; |
| 2397 | } | 2397 | } |
| 2398 | case id<TableLit_t>(): { | 2398 | case id<TableLit_t>(): { |
| 2399 | auto tableLit = static_cast<TableLit_t*>(value); | 2399 | auto tableLit = static_cast<TableLit_t*>(value); |
| @@ -2402,7 +2402,7 @@ private: | |||
| 2402 | std::string preDefine = getPreDefineLine(assignment); | 2402 | std::string preDefine = getPreDefineLine(assignment); |
| 2403 | transformSpreadTable(tableLit->values.objects(), out, ExpUsage::Assignment, expList, false); | 2403 | transformSpreadTable(tableLit->values.objects(), out, ExpUsage::Assignment, expList, false); |
| 2404 | out.back().insert(0, preDefine); | 2404 | out.back().insert(0, preDefine); |
| 2405 | return; | 2405 | return false; |
| 2406 | } | 2406 | } |
| 2407 | break; | 2407 | break; |
| 2408 | } | 2408 | } |
| @@ -2413,31 +2413,31 @@ private: | |||
| 2413 | std::string preDefine = getPreDefineLine(assignment); | 2413 | std::string preDefine = getPreDefineLine(assignment); |
| 2414 | transformSpreadTable(tableBlock->values.objects(), out, ExpUsage::Assignment, expList, false); | 2414 | transformSpreadTable(tableBlock->values.objects(), out, ExpUsage::Assignment, expList, false); |
| 2415 | out.back().insert(0, preDefine); | 2415 | out.back().insert(0, preDefine); |
| 2416 | return; | 2416 | return false; |
| 2417 | } | 2417 | } |
| 2418 | break; | 2418 | break; |
| 2419 | } | 2419 | } |
| 2420 | } | 2420 | } |
| 2421 | auto exp = ast_cast<Exp_t>(value); | 2421 | auto exp = ast_cast<Exp_t>(value); |
| 2422 | BREAK_IF(!exp); | 2422 | BREAK_IF(!exp); |
| 2423 | if (isPureBackcall(exp)) { | 2423 | if (isPurePipeChain(exp)) { |
| 2424 | auto expList = assignment->expList.get(); | 2424 | auto expList = assignment->expList.get(); |
| 2425 | transformExp(exp, out, ExpUsage::Assignment, expList); | 2425 | transformExp(exp, out, ExpUsage::Assignment, expList); |
| 2426 | return; | 2426 | return false; |
| 2427 | } else if (isPureNilCoalesed(exp)) { | 2427 | } else if (isPureNilCoalesed(exp)) { |
| 2428 | auto expList = assignment->expList.get(); | 2428 | auto expList = assignment->expList.get(); |
| 2429 | transformNilCoalesedExp(exp, out, ExpUsage::Assignment, expList); | 2429 | transformNilCoalesedExp(exp, out, ExpUsage::Assignment, expList); |
| 2430 | return; | 2430 | return false; |
| 2431 | } else if (auto unary = unaryGeneratingAnonFunc(exp)) { | 2431 | } else if (auto unary = unaryGeneratingAnonFunc(exp)) { |
| 2432 | std::string preDefine = getPreDefineLine(assignment); | 2432 | std::string preDefine = getPreDefineLine(assignment); |
| 2433 | auto expList = assignment->expList.get(); | 2433 | auto expList = assignment->expList.get(); |
| 2434 | transformUnaryExp(unary, out, ExpUsage::Assignment, expList); | 2434 | transformUnaryExp(unary, out, ExpUsage::Assignment, expList); |
| 2435 | out.back().insert(0, preDefine); | 2435 | out.back().insert(0, preDefine); |
| 2436 | return; | 2436 | return false; |
| 2437 | } else if (isConditionChaining(exp)) { | 2437 | } else if (isConditionChaining(exp)) { |
| 2438 | auto expList = assignment->expList.get(); | 2438 | auto expList = assignment->expList.get(); |
| 2439 | transformExp(exp, out, ExpUsage::Assignment, expList); | 2439 | transformExp(exp, out, ExpUsage::Assignment, expList); |
| 2440 | return; | 2440 | return false; |
| 2441 | } | 2441 | } |
| 2442 | auto singleVal = singleValueFrom(exp); | 2442 | auto singleVal = singleValueFrom(exp); |
| 2443 | BREAK_IF(!singleVal); | 2443 | BREAK_IF(!singleVal); |
| @@ -2451,13 +2451,13 @@ private: | |||
| 2451 | std::string preDefine = getPreDefineLine(assignment); | 2451 | std::string preDefine = getPreDefineLine(assignment); |
| 2452 | transformChainValue(chainValue, out, ExpUsage::Assignment, expList, false, optionalDestruct); | 2452 | transformChainValue(chainValue, out, ExpUsage::Assignment, expList, false, optionalDestruct); |
| 2453 | out.back().insert(0, preDefine); | 2453 | out.back().insert(0, preDefine); |
| 2454 | return; | 2454 | return false; |
| 2455 | } | 2455 | } |
| 2456 | case ChainType::HasKeyword: | 2456 | case ChainType::HasKeyword: |
| 2457 | case ChainType::HasUnicode: | 2457 | case ChainType::HasUnicode: |
| 2458 | case ChainType::Macro: | 2458 | case ChainType::Macro: |
| 2459 | transformChainValue(chainValue, out, ExpUsage::Assignment, expList); | 2459 | transformChainValue(chainValue, out, ExpUsage::Assignment, expList); |
| 2460 | return; | 2460 | return false; |
| 2461 | case ChainType::Common: | 2461 | case ChainType::Common: |
| 2462 | case ChainType::EndWithEOP: | 2462 | case ChainType::EndWithEOP: |
| 2463 | case ChainType::Metatable: | 2463 | case ChainType::Metatable: |
| @@ -2468,6 +2468,7 @@ private: | |||
| 2468 | auto info = extractDestructureInfo(assignment, false, optionalDestruct); | 2468 | auto info = extractDestructureInfo(assignment, false, optionalDestruct); |
| 2469 | if (info.destructures.empty()) { | 2469 | if (info.destructures.empty()) { |
| 2470 | transformAssignmentCommon(assignment, out); | 2470 | transformAssignmentCommon(assignment, out); |
| 2471 | return true; | ||
| 2471 | } else { | 2472 | } else { |
| 2472 | auto x = assignment; | 2473 | auto x = assignment; |
| 2473 | str_list temp; | 2474 | str_list temp; |
| @@ -2733,6 +2734,7 @@ private: | |||
| 2733 | } | 2734 | } |
| 2734 | out.push_back(join(temp)); | 2735 | out.push_back(join(temp)); |
| 2735 | } | 2736 | } |
| 2737 | return false; | ||
| 2736 | } | 2738 | } |
| 2737 | 2739 | ||
| 2738 | void transformAssignItem(ast_node* value, str_list& out) { | 2740 | void transformAssignItem(ast_node* value, str_list& out) { |
| @@ -5313,7 +5315,7 @@ private: | |||
| 5313 | if (auto valueList = returnNode->valueList.as<ExpListLow_t>()) { | 5315 | if (auto valueList = returnNode->valueList.as<ExpListLow_t>()) { |
| 5314 | if (valueList->exprs.size() == 1) { | 5316 | if (valueList->exprs.size() == 1) { |
| 5315 | auto exp = static_cast<Exp_t*>(valueList->exprs.back()); | 5317 | auto exp = static_cast<Exp_t*>(valueList->exprs.back()); |
| 5316 | if (isPureBackcall(exp)) { | 5318 | if (isPurePipeChain(exp)) { |
| 5317 | transformExp(exp, out, ExpUsage::Return); | 5319 | transformExp(exp, out, ExpUsage::Return); |
| 5318 | return; | 5320 | return; |
| 5319 | } else if (isPureNilCoalesed(exp)) { | 5321 | } else if (isPureNilCoalesed(exp)) { |
| @@ -10676,6 +10678,7 @@ private: | |||
| 10676 | 10678 | ||
| 10677 | void transformLocal(Local_t* local, str_list& out) { | 10679 | void transformLocal(Local_t* local, str_list& out) { |
| 10678 | str_list temp; | 10680 | str_list temp; |
| 10681 | bool defined = local->defined; | ||
| 10679 | if (!local->defined) { | 10682 | if (!local->defined) { |
| 10680 | local->defined = true; | 10683 | local->defined = true; |
| 10681 | transformLocalDef(local, temp); | 10684 | transformLocalDef(local, temp); |
| @@ -10704,7 +10707,26 @@ private: | |||
| 10704 | assign->values.push_back(tableBlock); | 10707 | assign->values.push_back(tableBlock); |
| 10705 | } | 10708 | } |
| 10706 | assignment->action.set(assign); | 10709 | assignment->action.set(assign); |
| 10707 | transformAssignment(assignment, temp); | 10710 | bool oneLined = transformAssignment(assignment, temp); |
| 10711 | for (auto val : assign->values.objects()) { | ||
| 10712 | if (auto value = singleValueFrom(val)) { | ||
| 10713 | if (auto spValue = value->item.as<SimpleValue_t>()) { | ||
| 10714 | if (auto funLit = spValue->value.as<FunLit_t>()) { | ||
| 10715 | if (!funLit->noRecursion) { | ||
| 10716 | oneLined = false; | ||
| 10717 | } | ||
| 10718 | break; | ||
| 10719 | } | ||
| 10720 | } | ||
| 10721 | } | ||
| 10722 | } | ||
| 10723 | if (!defined && oneLined && temp.size() == 2) { | ||
| 10724 | auto pos = temp.back().find_first_not_of(" \t"sv); | ||
| 10725 | if (pos != std::string::npos) { | ||
| 10726 | temp.back().insert(pos, "local "); | ||
| 10727 | temp.pop_front(); | ||
| 10728 | } | ||
| 10729 | } | ||
| 10708 | } | 10730 | } |
| 10709 | break; | 10731 | break; |
| 10710 | } | 10732 | } |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 5993ed5..ceb1f7c 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
| @@ -519,7 +519,7 @@ YueParser::YueParser() { | |||
| 519 | UpdateOp = | 519 | UpdateOp = |
| 520 | expr("..") | "//" | "or" | "and" | | 520 | expr("..") | "//" | "or" | "and" | |
| 521 | ">>" | "<<" | "??" | | 521 | ">>" | "<<" | "??" | |
| 522 | set("+-*/%&|"); | 522 | set("+-*/%&|^"); |
| 523 | 523 | ||
| 524 | Update = UpdateOp >> '=' >> space >> Exp; | 524 | Update = UpdateOp >> '=' >> space >> Exp; |
| 525 | 525 | ||
diff --git a/src/yuescript/yuescript.h b/src/yuescript/yuescript.h index ebe90cb..83a4350 100644 --- a/src/yuescript/yuescript.h +++ b/src/yuescript/yuescript.h | |||
| @@ -187,10 +187,10 @@ local function dump(what) | |||
| 187 | depth = depth or 0 | 187 | depth = depth or 0 |
| 188 | local t = type(what) | 188 | local t = type(what) |
| 189 | if "string" == t then | 189 | if "string" == t then |
| 190 | return "\"" .. tostring(what) .. "\"\n" | 190 | return "\"" .. tostring(what) .. "\"" |
| 191 | elseif "table" == t then | 191 | elseif "table" == t then |
| 192 | if seen[what] then | 192 | if seen[what] then |
| 193 | return "recursion(" .. tostring(what) .. ")...\n" | 193 | return "recursion(" .. tostring(what) .. ")..." |
| 194 | end | 194 | end |
| 195 | seen[what] = true | 195 | seen[what] = true |
| 196 | depth = depth + 1 | 196 | depth = depth + 1 |
| @@ -199,9 +199,9 @@ local function dump(what) | |||
| 199 | insert(lines, ('\t'):rep(depth) .. "[" .. tostring(k) .. "] = " .. _dump(v, depth)) | 199 | insert(lines, ('\t'):rep(depth) .. "[" .. tostring(k) .. "] = " .. _dump(v, depth)) |
| 200 | end | 200 | end |
| 201 | seen[what] = false | 201 | seen[what] = false |
| 202 | return "{\n" .. concat(lines) .. ('\t'):rep(depth - 1) .. "}\n" | 202 | return "{\n" .. concat(lines, "\n") .. "\n" .. ('\t'):rep(depth - 1) .. "}" |
| 203 | else | 203 | else |
| 204 | return tostring(what) .. "\n" | 204 | return tostring(what) |
| 205 | end | 205 | end |
| 206 | end | 206 | end |
| 207 | return _dump(what) | 207 | return _dump(what) |
