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) |