Skip to content

Commit 2afe1bf

Browse files
Feat: Tuple unpackaging implementation.
1 parent 82145d0 commit 2afe1bf

2 files changed

Lines changed: 32 additions & 6 deletions

File tree

compiler/src/modules/parser.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -680,10 +680,13 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
680680
fn for_stmt(&mut self) {
681681
self.advance();
682682

683-
let var = {
683+
let mut vars = Vec::new();
684+
loop {
684685
let t = self.advance();
685-
self.lexeme(&t).to_string()
686-
};
686+
vars.push(self.lexeme(&t).to_string());
687+
if !self.eat_if(TokenType::Comma) { break; }
688+
if matches!(self.peek(), Some(TokenType::In)) { break; }
689+
}
687690

688691
self.eat(TokenType::In);
689692
self.expr();
@@ -698,9 +701,18 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
698701
self.chunk.emit(OpCode::ForIter, 0);
699702
let fi = self.chunk.instructions.len() - 1;
700703

701-
let ver = self.increment_version(&var);
702-
let idx = self.chunk.push_name(&format!("{}_{}", var, ver));
703-
self.chunk.emit(OpCode::StoreName, idx);
704+
if vars.len() == 1 {
705+
let ver = self.increment_version(&vars[0]);
706+
let idx = self.chunk.push_name(&format!("{}_{}", vars[0], ver));
707+
self.chunk.emit(OpCode::StoreName, idx);
708+
} else {
709+
self.chunk.emit(OpCode::UnpackSequence, vars.len() as u16);
710+
for var in vars.iter().rev() {
711+
let ver = self.increment_version(var);
712+
let idx = self.chunk.push_name(&format!("{}_{}", var, ver));
713+
self.chunk.emit(OpCode::StoreName, idx);
714+
}
715+
}
704716

705717
self.eat(TokenType::Colon);
706718
self.compile_block();

compiler/tests/cases/parser_cases.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,5 +1098,19 @@
10981098
"instructions": [["MakeFunction",0], ["StoreName",0], ["ReturnValue",0]],
10991099
"annotations": {},
11001100
"functions": 1
1101+
},
1102+
{
1103+
"src": "for a, b in x:\n pass",
1104+
"constants": [],
1105+
"names": ["x_0", "b_1", "a_1", "a_0", "a_2", "b_0", "b_2"],
1106+
"instructions": [["LoadName",0], ["GetIter",0], ["ForIter",7], ["UnpackSequence",2], ["StoreName",1], ["StoreName",2], ["Jump",2], ["Phi",4], ["Phi",6], ["ReturnValue",0]],
1107+
"annotations": {}
1108+
},
1109+
{
1110+
"src": "for a, b, c in x:\n pass",
1111+
"constants": [],
1112+
"names": ["x_0", "c_1", "b_1", "a_1", "a_0", "a_2", "b_0", "b_2", "c_0", "c_2"],
1113+
"instructions": [["LoadName",0], ["GetIter",0], ["ForIter",8], ["UnpackSequence",3], ["StoreName",1], ["StoreName",2], ["StoreName",3], ["Jump",2], ["Phi",5], ["Phi",7], ["Phi",9], ["ReturnValue",0]],
1114+
"annotations": {}
11011115
}
11021116
]

0 commit comments

Comments
 (0)