Skip to content

Commit df26217

Browse files
committed
fix: empty table pattern in switch generates valid Lua code
- Add EmptyTableType enum to distinguish [] and {} patterns - [] (empty list) generates '#x == 0' check - {} (empty table) generates 'next(x) == nil' check - Fixes issue #249
1 parent ad0cd3a commit df26217

1 file changed

Lines changed: 39 additions & 4 deletions

File tree

src/yuescript/yue_compiler.cpp

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -478,11 +478,18 @@ class YueCompilerImpl {
478478
ast_ptr<true, Exp_t> defVal;
479479
};
480480

481+
enum class EmptyTableType {
482+
None,
483+
EmptyList,
484+
EmptyTable
485+
};
486+
481487
struct Destructure {
482488
ast_ptr<true, ast_node> value;
483489
std::string valueVar;
484490
std::list<DestructItem> items;
485491
ast_ptr<false, ExpListAssign_t> inlineAssignment;
492+
EmptyTableType emptyTableType = EmptyTableType::None;
486493
};
487494

488495
enum class ExpUsage {
@@ -3425,10 +3432,9 @@ class YueCompilerImpl {
34253432
break;
34263433
default: YUEE("AST node mismatch", destructNode); break;
34273434
}
3428-
if (dlist->empty()) {
3429-
if (!optional) {
3430-
throw CompileError("expect items to be destructured"sv, destructNode);
3431-
}
3435+
bool emptyTablePattern = dlist->empty();
3436+
if (emptyTablePattern && !optional) {
3437+
throw CompileError("expect items to be destructured"sv, destructNode);
34323438
}
34333439
for (auto item : *dlist) {
34343440
switch (item->get_id()) {
@@ -3554,6 +3560,26 @@ class YueCompilerImpl {
35543560
extraScope = true;
35553561
}
35563562
}
3563+
// Handle empty table pattern for switch matching
3564+
if (emptyTablePattern) {
3565+
Destructure emptyDestruct;
3566+
if (!varDefOnly) {
3567+
emptyDestruct.value = valueItems.back();
3568+
emptyDestruct.valueVar = singleVariableFrom(emptyDestruct.value, AccessType::None);
3569+
}
3570+
switch (destructNode->get_id()) {
3571+
case id<Comprehension_t>():
3572+
emptyDestruct.emptyTableType = EmptyTableType::EmptyList;
3573+
break;
3574+
case id<TableLit_t>():
3575+
case id<SimpleTable_t>():
3576+
emptyDestruct.emptyTableType = EmptyTableType::EmptyTable;
3577+
break;
3578+
default:
3579+
break;
3580+
}
3581+
destructs.push_back(std::move(emptyDestruct));
3582+
}
35573583
TableLit_t* tabs[] = {subDestruct.get(), subMetaDestruct.get()};
35583584
for (auto tab : tabs) {
35593585
if (!tab->values.empty()) {
@@ -12129,6 +12155,15 @@ class YueCompilerImpl {
1212912155
continue;
1213012156
}
1213112157
const auto& destruct = std::get<Destructure>(des);
12158+
// Handle empty table pattern
12159+
if (destruct.emptyTableType != EmptyTableType::None) {
12160+
if (destruct.emptyTableType == EmptyTableType::EmptyList) {
12161+
conds.push_back('#' + objVar + " == 0");
12162+
} else {
12163+
conds.push_back(globalVar("next"sv, branch, AccessType::Read) + '(' + objVar + ") == nil");
12164+
}
12165+
continue;
12166+
}
1213212167
for (const auto& item : destruct.items) {
1213312168
if (!item.defVal) {
1213412169
if (!isAssignable(item.target)) {

0 commit comments

Comments
 (0)