aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/yuescript/yue_ast.h2
-rw-r--r--src/yuescript/yue_compiler.cpp47
-rw-r--r--src/yuescript/yue_parser.cpp2
3 files changed, 35 insertions, 16 deletions
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h
index b1a369b..0008fd6 100644
--- a/src/yuescript/yue_ast.h
+++ b/src/yuescript/yue_ast.h
@@ -443,7 +443,7 @@ AST_END(CompInner)
443 443
444AST_NODE(Assign) 444AST_NODE(Assign)
445 ast_ptr<true, Seperator_t> sep; 445 ast_ptr<true, Seperator_t> sep;
446 ast_sel_list<true, With_t, If_t, Switch_t, TableBlock_t, Exp_t> values; 446 ast_sel_list<true, With_t, If_t, Switch_t, TableBlock_t, Exp_t, SpreadListExp_t> values;
447 AST_MEMBER(Assign, &sep, &values) 447 AST_MEMBER(Assign, &sep, &values)
448AST_END(Assign) 448AST_END(Assign)
449 449
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index ed0a587..8c28e61 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
81const std::string_view version = "0.29.7"sv; 81const std::string_view version = "0.29.8"sv;
82const std::string_view extension = "yue"sv; 82const std::string_view extension = "yue"sv;
83 83
84class CompileError : public std::logic_error { 84class CompileError : public std::logic_error {
@@ -2321,15 +2321,27 @@ private:
2321 transformAssignment(newAssignment, temp); 2321 transformAssignment(newAssignment, temp);
2322 varName = objVar; 2322 varName = objVar;
2323 } 2323 }
2324 auto newAssignment = x->new_ptr<ExpListAssign_t>(); 2324 if (auto spread = ast_cast<SpreadListExp_t>(*vit)) {
2325 newAssignment->expList.set(toAst<ExpList_t>(varName + "[#"s + varName + "+1]"s, x)); 2325 auto lenVar = getUnusedName("_len_"sv);
2326 auto assign = x->new_ptr<Assign_t>(); 2326 forceAddToScope(lenVar);
2327 if (vit == values.end()) { 2327 temp.push_back(indent() + "local "s + lenVar + " = #"s + varName + " + 1"s + nll(spread));
2328 throw CompileError("right value missing"sv, values.front()); 2328 auto elmVar = getUnusedName("_elm_"sv);
2329 _buf << varName << '[' << lenVar << "],"s << lenVar << "="s << elmVar << ',' << lenVar << "+1 for "s << elmVar << " in *nil"s;
2330 auto stmt = toAst<Statement_t>(clearBuf(), spread);
2331 auto comp = stmt->appendix->item.to<CompInner_t>();
2332 ast_to<CompForEach_t>(comp->items.front())->loopValue.to<StarExp_t>()->value.set(spread->exp);
2333 transformStatement(stmt, temp);
2334 } else {
2335 auto newAssignment = x->new_ptr<ExpListAssign_t>();
2336 newAssignment->expList.set(toAst<ExpList_t>(varName + "[#"s + varName + "+1]"s, x));
2337 auto assign = x->new_ptr<Assign_t>();
2338 if (vit == values.end()) {
2339 throw CompileError("right value missing"sv, values.front());
2340 }
2341 assign->values.push_back(*vit);
2342 newAssignment->action.set(assign);
2343 transformAssignment(newAssignment, temp);
2329 } 2344 }
2330 assign->values.push_back(*vit);
2331 newAssignment->action.set(assign);
2332 transformAssignment(newAssignment, temp);
2333 if (extraScoped) { 2345 if (extraScoped) {
2334 popScope(); 2346 popScope();
2335 temp.push_back(indent() + "end"s + nlr(x)); 2347 temp.push_back(indent() + "end"s + nlr(x));
@@ -2848,6 +2860,7 @@ private:
2848 case id<Switch_t>(): transformSwitch(static_cast<Switch_t*>(value), out, ExpUsage::Closure); break; 2860 case id<Switch_t>(): transformSwitch(static_cast<Switch_t*>(value), out, ExpUsage::Closure); break;
2849 case id<TableBlock_t>(): transformTableBlock(static_cast<TableBlock_t*>(value), out); break; 2861 case id<TableBlock_t>(): transformTableBlock(static_cast<TableBlock_t*>(value), out); break;
2850 case id<Exp_t>(): transformExp(static_cast<Exp_t*>(value), out, ExpUsage::Closure); break; 2862 case id<Exp_t>(): transformExp(static_cast<Exp_t*>(value), out, ExpUsage::Closure); break;
2863 case id<SpreadListExp_t>(): throw CompileError("can only be used for ranged table append assignments"sv, value); break;
2851 default: YUEE("AST node mismatch", value); break; 2864 default: YUEE("AST node mismatch", value); break;
2852 } 2865 }
2853 } 2866 }
@@ -8268,9 +8281,16 @@ private:
8268 } 8281 }
8269 return; 8282 return;
8270 } 8283 }
8271 auto def = ast_cast<NormalDef_t>(comp->items.front()); 8284 ast_node* value = nullptr;
8272 if (!def || def->defVal) { 8285 bool isSpread = ast_is<SpreadListExp_t>(comp->items.front());
8273 throw CompileError("invalid comprehension expression", comp->items.front()); 8286 if (isSpread) {
8287 value = comp->items.front();
8288 } else {
8289 auto def = ast_cast<NormalDef_t>(comp->items.front());
8290 if (!def || def->defVal) {
8291 throw CompileError("invalid comprehension expression", comp->items.front());
8292 }
8293 value = def->item.get();
8274 } 8294 }
8275 bool extraScope = false; 8295 bool extraScope = false;
8276 switch (usage) { 8296 switch (usage) {
@@ -8294,7 +8314,6 @@ private:
8294 default: 8314 default:
8295 break; 8315 break;
8296 } 8316 }
8297 auto value = def->item.get();
8298 auto compInner = static_cast<CompInner_t*>(comp->items.back()); 8317 auto compInner = static_cast<CompInner_t*>(comp->items.back());
8299 str_list temp; 8318 str_list temp;
8300 std::string accumVar = getUnusedName("_accum_"sv); 8319 std::string accumVar = getUnusedName("_accum_"sv);
@@ -8318,7 +8337,7 @@ private:
8318 } 8337 }
8319 } 8338 }
8320 { 8339 {
8321 auto assignLeft = toAst<ExpList_t>(accumVar + '[' + lenVar + ']', x); 8340 auto assignLeft = toAst<ExpList_t>(accumVar + '[' + lenVar + (isSpread ? "][]"s : "]"s), x);
8322 auto assign = x->new_ptr<Assign_t>(); 8341 auto assign = x->new_ptr<Assign_t>();
8323 assign->values.push_back(value); 8342 assign->values.push_back(value);
8324 auto assignment = x->new_ptr<ExpListAssign_t>(); 8343 auto assignment = x->new_ptr<ExpListAssign_t>();
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index 44baced..fccb6fb 100644
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -547,7 +547,7 @@ YueParser::YueParser() {
547 547
548 Assign = '=' >> space >> Seperator >> ( 548 Assign = '=' >> space >> Seperator >> (
549 With | If | Switch | TableBlock | 549 With | If | Switch | TableBlock |
550 Exp >> *(space >> set(",;") >> space >> Exp) 550 (SpreadListExp | Exp) >> *(space >> set(",;") >> space >> (SpreadListExp | Exp))
551 ); 551 );
552 552
553 UpdateOp = 553 UpdateOp =