mirror of
https://github.com/Noratrieb/dilaria.git
synced 2026-01-14 09:25:02 +01:00
break!
This commit is contained in:
parent
06dd53525a
commit
628899dde7
9 changed files with 145 additions and 8 deletions
|
|
@ -56,6 +56,11 @@ struct Compiler<'bc, 'gc> {
|
|||
/// the current local variables that are in scope, only needed for compiling
|
||||
env: Rc<RefCell<Env>>,
|
||||
rt: &'gc mut RtAlloc,
|
||||
|
||||
/// How nested the current loop is, required for break offsets
|
||||
loop_nesting: usize,
|
||||
/// All break instructions currently in need of an offset. K=loop_nesting, V=break_indices
|
||||
breaks: HashMap<usize, std::vec::Vec<usize>>,
|
||||
}
|
||||
|
||||
pub fn compile<'ast, 'bc, 'gc>(
|
||||
|
|
@ -69,6 +74,8 @@ pub fn compile<'ast, 'bc, 'gc>(
|
|||
bump: bytecode_bump,
|
||||
env: Rc::new(RefCell::new(Env::default())),
|
||||
rt,
|
||||
loop_nesting: 0,
|
||||
breaks: HashMap::default(),
|
||||
};
|
||||
|
||||
compiler.compile(ast)?;
|
||||
|
|
@ -200,12 +207,17 @@ impl<'bc, 'gc> Compiler<'bc, 'gc> {
|
|||
*/
|
||||
|
||||
let first_stmt_idx = self.code_len();
|
||||
|
||||
self.loop_nesting += 1;
|
||||
|
||||
self.compile_block(ast_block)?;
|
||||
|
||||
let jmp_offset = self.back_jmp_offset(first_stmt_idx);
|
||||
|
||||
self.push_instr(Instr::Jmp(jmp_offset), StackChange::None, span);
|
||||
|
||||
self.end_loop();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -219,6 +231,9 @@ impl<'bc, 'gc> Compiler<'bc, 'gc> {
|
|||
*/
|
||||
|
||||
let cond_index = self.code_len();
|
||||
|
||||
self.loop_nesting += 1;
|
||||
|
||||
self.compile_expr(&while_stmt.cond)?;
|
||||
|
||||
let jmp_false_idx =
|
||||
|
|
@ -232,11 +247,18 @@ impl<'bc, 'gc> Compiler<'bc, 'gc> {
|
|||
let jmp_offset = self.forward_jmp_offset(jmp_false_idx as isize);
|
||||
self.change_instr(jmp_false_idx, Instr::JmpFalse(jmp_offset));
|
||||
|
||||
self.end_loop();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compile_break(&mut self, _: Span) -> CResult {
|
||||
todo!()
|
||||
fn compile_break(&mut self, span: Span) -> CResult {
|
||||
let break_idx = self.push_instr(Instr::Jmp(0), StackChange::None, span);
|
||||
self.breaks
|
||||
.entry(self.loop_nesting)
|
||||
.or_default()
|
||||
.push(break_idx);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compile_return(&mut self, _: &Option<Expr>, _: Span) -> CResult {
|
||||
|
|
@ -337,6 +359,17 @@ impl<'bc, 'gc> Compiler<'bc, 'gc> {
|
|||
todo!()
|
||||
}
|
||||
|
||||
fn end_loop(&mut self) {
|
||||
let breaks = self.breaks.remove(&self.loop_nesting);
|
||||
if let Some(breaks) = breaks {
|
||||
for brk in breaks {
|
||||
let offset = self.forward_jmp_offset(brk as isize);
|
||||
self.change_instr(brk, Instr::Jmp(offset));
|
||||
}
|
||||
}
|
||||
self.loop_nesting -= 1;
|
||||
}
|
||||
|
||||
fn current_stack_top(&self) -> usize {
|
||||
let block = &self.blocks[self.current_block];
|
||||
// we want the stack position, not the size, so the `- 1`
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ impl<'bc> Vm<'bc, '_> {
|
|||
}
|
||||
self.pc += 1;
|
||||
// debug stack size assertion
|
||||
todo!()
|
||||
// todo!()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
8
test.dil
8
test.dil
|
|
@ -1,7 +1,5 @@
|
|||
let i = 0;
|
||||
|
||||
while i < 100000 {
|
||||
i = i + 1;
|
||||
loop {
|
||||
break;
|
||||
}
|
||||
|
||||
print "done";
|
||||
print "hi";
|
||||
|
|
@ -140,3 +140,74 @@ while i < 100 {
|
|||
}
|
||||
"#
|
||||
);
|
||||
|
||||
run_test!(
|
||||
break_out_loop,
|
||||
r#"
|
||||
print "Start";
|
||||
|
||||
loop {
|
||||
break;
|
||||
print "WRONG";
|
||||
}
|
||||
|
||||
print "Good end";
|
||||
"#
|
||||
);
|
||||
|
||||
run_test!(
|
||||
break_out_while,
|
||||
r#"
|
||||
print "Start";
|
||||
|
||||
while true {
|
||||
break;
|
||||
print "WRONG";
|
||||
}
|
||||
|
||||
print "Good end";
|
||||
"#
|
||||
);
|
||||
|
||||
run_test!(
|
||||
fizzbuzz_with_loop,
|
||||
r#"
|
||||
let i = 1;
|
||||
|
||||
loop {
|
||||
if i % 15 == 0 {
|
||||
print "FizzBuzz";
|
||||
} else if i % 5 == 0 {
|
||||
print "Buzz";
|
||||
} else if i % 3 == 0 {
|
||||
print "Fizz";
|
||||
} else {
|
||||
print i;
|
||||
}
|
||||
i = i + 1;
|
||||
|
||||
if i >= 100 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
"#
|
||||
);
|
||||
|
||||
run_test!(
|
||||
nested_loop_break,
|
||||
r#"
|
||||
print "Start";
|
||||
loop {
|
||||
print "Start inner";
|
||||
loop {
|
||||
print "inside inner";
|
||||
break;
|
||||
print "WRONG";
|
||||
}
|
||||
print "Outside inner";
|
||||
break;
|
||||
print "WRONG";
|
||||
}
|
||||
print "End";
|
||||
"#
|
||||
);
|
||||
|
|
|
|||
7
tests/snapshots/control_flow__break_out.snap
Normal file
7
tests/snapshots/control_flow__break_out.snap
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
source: tests/control_flow.rs
|
||||
assertion_line: 144
|
||||
expression: output
|
||||
|
||||
---
|
||||
"Start\nGood end\n"
|
||||
7
tests/snapshots/control_flow__break_out_loop.snap
Normal file
7
tests/snapshots/control_flow__break_out_loop.snap
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
source: tests/control_flow.rs
|
||||
assertion_line: 144
|
||||
expression: output
|
||||
|
||||
---
|
||||
"Start\nGood end\n"
|
||||
7
tests/snapshots/control_flow__break_out_while.snap
Normal file
7
tests/snapshots/control_flow__break_out_while.snap
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
source: tests/control_flow.rs
|
||||
assertion_line: 158
|
||||
expression: output
|
||||
|
||||
---
|
||||
"Start\nGood end\n"
|
||||
7
tests/snapshots/control_flow__fizzbuzz_with_loop.snap
Normal file
7
tests/snapshots/control_flow__fizzbuzz_with_loop.snap
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
source: tests/control_flow.rs
|
||||
assertion_line: 158
|
||||
expression: output
|
||||
|
||||
---
|
||||
"1\n2\nFizz\n4\nBuzz\nFizz\n7\n8\nFizz\nBuzz\n11\nFizz\n13\n14\nFizzBuzz\n16\n17\nFizz\n19\nBuzz\nFizz\n22\n23\nFizz\nBuzz\n26\nFizz\n28\n29\nFizzBuzz\n31\n32\nFizz\n34\nBuzz\nFizz\n37\n38\nFizz\nBuzz\n41\nFizz\n43\n44\nFizzBuzz\n46\n47\nFizz\n49\nBuzz\nFizz\n52\n53\nFizz\nBuzz\n56\nFizz\n58\n59\nFizzBuzz\n61\n62\nFizz\n64\nBuzz\nFizz\n67\n68\nFizz\nBuzz\n71\nFizz\n73\n74\nFizzBuzz\n76\n77\nFizz\n79\nBuzz\nFizz\n82\n83\nFizz\nBuzz\n86\nFizz\n88\n89\nFizzBuzz\n91\n92\nFizz\n94\nBuzz\nFizz\n97\n98\nFizz\n"
|
||||
7
tests/snapshots/control_flow__nested_loop_break.snap
Normal file
7
tests/snapshots/control_flow__nested_loop_break.snap
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
source: tests/control_flow.rs
|
||||
assertion_line: 196
|
||||
expression: output
|
||||
|
||||
---
|
||||
"Start\nStart inner\ninside inner\nOutside inner\nEnd\n"
|
||||
Loading…
Add table
Add a link
Reference in a new issue