Skip to content

Commit d7c543a

Browse files
Fix: SSA phi-nodes, for-loop join points, and inline block parsing.
1 parent 785f8f6 commit d7c543a

2 files changed

Lines changed: 26 additions & 19 deletions

File tree

compiler/src/modules/parser.rs

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -158,16 +158,22 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
158158
if let Some(j) = self.join_stack.pop() {
159159
let post = self.ssa_versions.clone();
160160
self.ssa_versions = j.backup;
161-
for (name, post_ver) in &post {
162-
let pre_ver = self.ssa_versions.get(name).copied().unwrap_or(0);
163-
if *post_ver != pre_ver {
164-
// parte desde post_ver, no desde backup, evita colisión
165-
self.ssa_versions.insert(name.to_string(), *post_ver);
166-
let new_ver = self.increment_version(name);
167-
let ssa = format!("{}_{}", name, new_ver);
168-
let i = self.chunk.push_name(&ssa);
169-
self.chunk.emit(OpCode::Phi, i);
170-
}
161+
162+
let mut diffs: Vec<(String, u32)> = post
163+
.into_iter()
164+
.filter(|(name, post_ver)| {
165+
self.ssa_versions.get(name).copied().unwrap_or(0) != *post_ver
166+
})
167+
.collect();
168+
169+
diffs.sort_by(|(a, _), (b, _)| a.cmp(b));
170+
171+
for (name, post_ver) in diffs {
172+
self.ssa_versions.insert(name.clone(), post_ver);
173+
let new_ver = self.increment_version(&name);
174+
let ssa = format!("{}_{}", name, new_ver);
175+
let i = self.chunk.push_name(&ssa);
176+
self.chunk.emit(OpCode::Phi, i);
171177
}
172178
}
173179
}
@@ -283,6 +289,8 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
283289
self.expr();
284290
self.chunk.emit(OpCode::GetIter, 0);
285291

292+
self.enter_block(); // ← snapshot pre-loop
293+
286294
let loop_start = self.chunk.instructions.len() as u16;
287295
self.loop_starts.push(loop_start);
288296
self.loop_breaks.push(vec![]);
@@ -294,12 +302,14 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
294302
self.chunk.emit(OpCode::StoreName, idx);
295303

296304
self.eat(TokenType::Colon);
297-
self.compile_block(); // ← correcto
305+
self.compile_block();
298306

299307
self.chunk.emit(OpCode::Jump, loop_start);
300308
self.patch(fi);
301309
self.loop_starts.pop();
302310
for pos in self.loop_breaks.pop().unwrap_or_default() { self.patch(pos); }
311+
312+
self.commit_block(); // ← phi-nodes al salir
303313
}
304314

305315
// helpers
@@ -314,27 +324,24 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
314324
}
315325

316326
fn compile_block(&mut self) {
317-
self.eat_if(TokenType::Indent);
327+
let indented = self.eat_if(TokenType::Indent);
318328

319329
while !self.at_end() {
320330
if matches!(self.peek(), Some(TokenType::Dedent)) {
321331
self.advance();
322332
break;
323333
}
324-
325334
if matches!(self.peek(), Some(TokenType::Newline | TokenType::Nl)) {
326335
self.advance();
327336
continue;
328337
}
329-
330338
let is_compound = matches!(self.peek(),
331339
Some(TokenType::For | TokenType::If | TokenType::While | TokenType::Def));
332-
333-
self.stmt(); // ← ya lo tienes, perfecto
334-
340+
self.stmt();
335341
if !self.at_end() && !is_compound {
336342
self.chunk.emit(OpCode::PopTop, 0);
337343
}
344+
if !indented { break; } // ← única línea que cambia
338345
}
339346
}
340347

compiler/tests/cases/parser_cases.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@
5151
{
5252
"src": "total = 0\nfor i in range(5):\ntotal = total + i",
5353
"constants": ["0", "5"],
54-
"names": ["total_1", "i_1", "total_2"],
55-
"instructions": [["LoadConst",0], ["StoreName",0], ["PopTop",0], ["LoadConst",1], ["CallRange",1], ["GetIter",0], ["ForIter",14], ["StoreName",1], ["LoadName",0], ["LoadName",1], ["Add",0], ["StoreName",2], ["PopTop",0], ["Jump",6], ["ReturnValue",0]],
54+
"names": ["total_1", "i_1", "total_2", "i_2", "total_3"],
55+
"instructions": [["LoadConst",0], ["StoreName",0], ["PopTop",0], ["LoadConst",1], ["CallRange",1], ["GetIter",0], ["ForIter",14], ["StoreName",1], ["LoadName",0], ["LoadName",1], ["Add",0], ["StoreName",2], ["PopTop",0], ["Jump",6], ["Phi",3], ["Phi",4], ["ReturnValue",0]],
5656
"annotations": {}
5757
},
5858
{

0 commit comments

Comments
 (0)