Skip to content

Commit 13c8068

Browse files
Feat: break, continue, augmented assign, list indexing, loop stack.
1 parent 1341ca2 commit 13c8068

1 file changed

Lines changed: 44 additions & 10 deletions

File tree

compiler/src/modules/parser.rs

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ pub enum OpCode {
5555
CallSorted, CallEnumerate, CallZip, CallList, CallTuple, CallDict,
5656
CallIsInstance, CallSet, CallInput, CallOrd, BuildDict, BuildList,
5757
NotEq, Lt, Gt, LtEq, GtEq, And,
58-
Or, Not, JumpIfFalse, Jump, GetIter, ForIter
58+
Or, Not, JumpIfFalse, Jump, GetIter, ForIter,
59+
GetItem
5960
}
6061

6162
#[derive(Debug)] pub struct Instruction { pub opcode: OpCode, pub operand: u16 }
@@ -89,6 +90,8 @@ pub struct Parser<'src, I: Iterator<Item = Token>> {
8990
chunk: SSAChunk,
9091
ssa_versions: HashMap<String, u32>,
9192
join_stack: Vec<JoinNode>,
93+
loop_starts: Vec<u16>, // continue salta aquí
94+
loop_breaks: Vec<Vec<usize>> // break: posiciones a patchear
9295
}
9396

9497
fn parse_string(s: &str) -> String {
@@ -116,7 +119,7 @@ fn unescape(s: &str) -> String {
116119

117120
impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
118121
pub fn new(source: &'src str, iter: I) -> Self {
119-
Self { source, tokens: iter.peekable(), chunk: SSAChunk::default(), ssa_versions: HashMap::new(), join_stack: Vec::new() }
122+
Self { source, tokens: iter.peekable(), chunk: SSAChunk::default(), ssa_versions: HashMap::new(), join_stack: Vec::new(), loop_starts: Vec::new(), loop_breaks: Vec::new() }
120123
}
121124

122125
pub fn parse(mut self) -> SSAChunk {
@@ -181,13 +184,29 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
181184
fn at_end(&mut self) -> bool { self.peek().is_none() }
182185
fn lexeme(&self, t: &Token) -> &'src str { &self.source[t.start..t.end] }
183186

187+
fn store_name(&mut self, name: String) {
188+
let ver = self.increment_version(&name);
189+
let i = self.chunk.push_name(&format!("{}_{}", name, ver));
190+
self.chunk.emit(OpCode::StoreName, i);
191+
}
192+
184193
fn stmt(&mut self) {
185194
match self.peek() {
186195
Some(TokenType::If) => self.if_stmt(),
187196
Some(TokenType::While) => self.while_stmt(),
188197
Some(TokenType::For) => self.for_stmt(),
189198
Some(TokenType::Name) => { let t = self.advance(); self.name_stmt(t); }
190199
Some(TokenType::Def) => { self.advance(); self.func_def(); }
200+
Some(TokenType::Break) => {
201+
self.advance();
202+
self.chunk.emit(OpCode::Jump, 0);
203+
self.loop_breaks.last_mut().unwrap().push(self.chunk.instructions.len() - 1);
204+
}
205+
Some(TokenType::Continue) => {
206+
self.advance();
207+
let start = *self.loop_starts.last().unwrap();
208+
self.chunk.emit(OpCode::Jump, start);
209+
}
191210
Some(TokenType::Return) => {
192211
self.advance();
193212
if matches!(self.peek(), Some(TokenType::Newline | TokenType::Endmarker)) {
@@ -205,13 +224,17 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
205224
self.advance();
206225
self.enter_block();
207226
let loop_start = self.chunk.instructions.len() as u16;
227+
self.loop_starts.push(loop_start);
228+
self.loop_breaks.push(vec![]);
208229
self.expr();
209230
self.chunk.emit(OpCode::JumpIfFalse, 0);
210231
let jf = self.chunk.instructions.len() - 1;
211232
self.eat(TokenType::Colon);
212233
self.stmt();
213234
self.chunk.emit(OpCode::Jump, loop_start);
214235
self.patch(jf);
236+
self.loop_starts.pop();
237+
for pos in self.loop_breaks.pop().unwrap_or_default() { self.patch(pos); }
215238
self.commit_block();
216239
}
217240

@@ -261,6 +284,8 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
261284
self.chunk.emit(OpCode::GetIter, 0);
262285

263286
let loop_start = self.chunk.instructions.len() as u16;
287+
self.loop_starts.push(loop_start);
288+
self.loop_breaks.push(vec![]);
264289
self.chunk.emit(OpCode::ForIter, 0);
265290
let fi = self.chunk.instructions.len() - 1;
266291

@@ -270,9 +295,11 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
270295

271296
self.eat(TokenType::Colon);
272297
self.stmt();
273-
self.chunk.emit(OpCode::PopTop, 0); // ← nuevo
298+
self.chunk.emit(OpCode::PopTop, 0);
274299
self.chunk.emit(OpCode::Jump, loop_start);
275300
self.patch(fi);
301+
self.loop_starts.pop();
302+
for pos in self.loop_breaks.pop().unwrap_or_default() { self.patch(pos); }
276303
}
277304

278305
// helpers
@@ -342,8 +369,12 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
342369

343370
// assign y call no necesitan la cadena de precedencia
344371
match self.peek() {
345-
Some(TokenType::Equal) => { self.assign(name); return; }
346-
Some(TokenType::Lpar) => { self.call(name); return; }
372+
Some(TokenType::Equal) => { self.assign(name); return; }
373+
Some(TokenType::PlusEqual) => { self.advance(); self.emit_load_ssa(name.clone()); self.expr(); self.chunk.emit(OpCode::Add, 0); self.store_name(name); return; }
374+
Some(TokenType::MinEqual) => { self.advance(); self.emit_load_ssa(name.clone()); self.expr(); self.chunk.emit(OpCode::Sub, 0); self.store_name(name); return; }
375+
Some(TokenType::StarEqual) => { self.advance(); self.emit_load_ssa(name.clone()); self.expr(); self.chunk.emit(OpCode::Mul, 0); self.store_name(name); return; }
376+
Some(TokenType::SlashEqual) => { self.advance(); self.emit_load_ssa(name.clone()); self.expr(); self.chunk.emit(OpCode::Div, 0); self.store_name(name); return; }
377+
Some(TokenType::Lpar) => { self.call(name); return; }
347378
_ => {}
348379
}
349380

@@ -434,6 +465,12 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
434465
TokenType::Lpar => { self.expr(); self.eat(TokenType::Rpar); }
435466
_ => {}
436467
}
468+
while matches!(self.peek(), Some(TokenType::Lsqb)) {
469+
self.advance();
470+
self.expr();
471+
self.eat(TokenType::Rsqb);
472+
self.chunk.emit(OpCode::GetItem, 0);
473+
}
437474
}
438475

439476
fn name(&mut self, t: Token) { // solo desde expr()
@@ -445,13 +482,10 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
445482
}
446483
}
447484

448-
fn assign(&mut self, name: String) {
485+
fn assign(&mut self, name: String) {
449486
self.advance();
450487
self.expr();
451-
let ver = self.increment_version(&name);
452-
let ssa = format!("{}_{}", name, ver);
453-
let i = self.chunk.push_name(&ssa);
454-
self.chunk.emit(OpCode::StoreName, i);
488+
self.store_name(name);
455489
}
456490

457491
fn parse_args(&mut self) -> u16 {

0 commit comments

Comments
 (0)