Skip to content

Commit c159da6

Browse files
Fix: Correct Phi fuunctionality.
1 parent d7c543a commit c159da6

1 file changed

Lines changed: 70 additions & 34 deletions

File tree

compiler/src/modules/parser.rs

Lines changed: 70 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ pub struct SSAChunk {
7171
pub names: Vec<String>,
7272
pub functions: Vec<(Vec<String>, SSAChunk)>,
7373
pub annotations: HashMap<String, String>,
74+
pub phi_sources: Vec<(u16, u16)>
7475
}
7576

7677
impl SSAChunk {
@@ -83,7 +84,8 @@ impl SSAChunk {
8384
}
8485

8586
struct JoinNode {
86-
backup: HashMap<String, u32>
87+
backup: HashMap<String, u32>,
88+
then: Option<HashMap<String, u32>>
8789
}
8890

8991
pub struct Parser<'src, I: Iterator<Item = Token>> {
@@ -138,9 +140,10 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
138140
fn current_version(&self, name: &str) -> u32 { self.ssa_versions.get(name).copied().unwrap_or(0) }
139141

140142
fn increment_version(&mut self, name: &str) -> u32 {
141-
let v = self.current_version(name) + 1;
142-
self.ssa_versions.insert(name.to_string(), v);
143-
v
143+
let current = self.ssa_versions.get(name).copied().unwrap_or(0);
144+
let new_ver = current + 1;
145+
self.ssa_versions.insert(name.to_string(), new_ver);
146+
new_ver
144147
}
145148

146149
fn emit_load_ssa(&mut self, name: String) {
@@ -151,41 +154,60 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
151154
}
152155

153156
fn enter_block(&mut self) {
154-
self.join_stack.push(JoinNode { backup: self.ssa_versions.clone() });
157+
self.join_stack.push(JoinNode { backup: self.ssa_versions.clone(), then: None });
155158
}
156159

157-
fn commit_block(&mut self) {
158-
if let Some(j) = self.join_stack.pop() {
159-
let post = self.ssa_versions.clone();
160-
self.ssa_versions = j.backup;
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);
177-
}
160+
fn mid_block(&mut self) {
161+
let Some(j) = self.join_stack.last_mut() else { return };
162+
163+
let current = self.ssa_versions.clone();
164+
j.then = Some(current.clone());
165+
166+
// Merge de versiones más altas (max) - inline y súper limpio
167+
let mut restored = j.backup.clone();
168+
for (name, &v) in &current {
169+
let e = restored.entry(name.clone()).or_insert(0);
170+
*e = (*e).max(v);
178171
}
172+
self.ssa_versions = restored;
179173
}
180174

181-
fn peek(&mut self) -> Option<TokenType> {
182-
loop {
183-
match self.tokens.peek().map(|t| t.kind.clone()) {
184-
Some(TokenType::Newline | TokenType::Nl | TokenType::Comment) => { self.tokens.next(); }
185-
Some(k) => return Some(k),
186-
None => return None,
187-
}
175+
fn commit_block(&mut self) {
176+
let Some(j) = self.join_stack.pop() else { return };
177+
let post = self.ssa_versions.clone();
178+
let (a, b) = match j.then {
179+
Some(t) => (t, post),
180+
None => (post, j.backup.clone())
181+
};
182+
183+
let mut names: Vec<_> = a.keys().chain(b.keys()).cloned().collect();
184+
names.sort(); names.dedup();
185+
186+
for name in names {
187+
let va = *a.get(&name).unwrap_or(&0);
188+
let vb = *b.get(&name).unwrap_or(&0);
189+
if va == vb { continue; }
190+
191+
let ia = if va == 0 {
192+
self.chunk.push_name(&format!("{}_{}", name, vb))
193+
} else {
194+
self.chunk.push_name(&format!("{}_{}", name, va))
195+
};
196+
let ib = if vb == 0 {
197+
self.chunk.push_name(&format!("{}_{}", name, va))
198+
} else {
199+
self.chunk.push_name(&format!("{}_{}", name, vb))
200+
};
201+
202+
let v = self.increment_version(&name);
203+
let ix = self.chunk.push_name(&format!("{}_{}", name, v));
204+
205+
self.chunk.phi_sources.push((ia, ib));
206+
self.chunk.emit(OpCode::Phi, ix);
207+
208+
self.ssa_versions.insert(name.clone(), v);
188209
}
210+
189211
}
190212

191213
fn advance(&mut self) -> Token { self.tokens.next().unwrap() }
@@ -265,6 +287,7 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
265287
self.advance(); // consume 'elif'
266288
self.chunk.emit(OpCode::Jump, 0);
267289
let jmp = self.chunk.instructions.len() - 1;
290+
self.mid_block();
268291
self.patch(jf);
269292
self.if_body(); // recursivo SIN enter/commit
270293
self.patch(jmp);
@@ -273,6 +296,7 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
273296
self.advance();
274297
self.chunk.emit(OpCode::Jump, 0);
275298
let jmp = self.chunk.instructions.len() - 1;
299+
self.mid_block();
276300
self.patch(jf);
277301
self.eat(TokenType::Colon);
278302
self.compile_block(); // ← usa block aquí
@@ -282,6 +306,16 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
282306
}
283307
}
284308

309+
fn peek(&mut self) -> Option<TokenType> {
310+
loop {
311+
match self.tokens.peek().map(|t| t.kind.clone()) {
312+
Some(TokenType::Newline | TokenType::Nl | TokenType::Comment) => { self.tokens.next(); }
313+
Some(k) => return Some(k),
314+
None => return None,
315+
}
316+
}
317+
}
318+
285319
fn for_stmt(&mut self) {
286320
self.advance();
287321
let var = { let t = self.advance(); self.lexeme(&t).to_string() };
@@ -620,7 +654,7 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
620654
}
621655

622656
fn compile_body(&mut self, params: &[String]) -> SSAChunk {
623-
let (mut saved_chunk, saved_ver) = (
657+
let (saved_chunk, saved_ver) = (
624658
std::mem::take(&mut self.chunk),
625659
std::mem::take(&mut self.ssa_versions),
626660
);
@@ -632,7 +666,9 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
632666
self.compile_block(); // ← SOLO esto
633667

634668
let body = std::mem::take(&mut self.chunk);
669+
635670
(self.chunk, self.ssa_versions) = (saved_chunk, saved_ver);
671+
636672
body
637673
}
638674

0 commit comments

Comments
 (0)