mirror of
https://github.com/Noratrieb/dilaria.git
synced 2026-01-14 17:35:03 +01:00
loop
This commit is contained in:
parent
a93412c3cd
commit
09deb07e85
4 changed files with 36 additions and 21 deletions
|
|
@ -14,6 +14,8 @@ pub struct FnBlock<'bc> {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum Instr {
|
pub enum Instr {
|
||||||
|
Nop,
|
||||||
|
|
||||||
/// Store the current value on the stack to the stack location with the local offset `usize`
|
/// Store the current value on the stack to the stack location with the local offset `usize`
|
||||||
Store(usize),
|
Store(usize),
|
||||||
/// Load the variable value from the local offset `usize` onto the stack
|
/// Load the variable value from the local offset `usize` onto the stack
|
||||||
|
|
@ -39,8 +41,8 @@ pub enum Instr {
|
||||||
/// Println the value on top of the stack
|
/// Println the value on top of the stack
|
||||||
Print,
|
Print,
|
||||||
|
|
||||||
/// If the current stack value is true, skip `usize` instructions.
|
/// If the current stack value is true, skip `usize` instructions. When jumping backwards
|
||||||
JumpFalse(usize),
|
JumpFalse(isize),
|
||||||
/// Same as `JumpCond`, but unconditional
|
/// Same as `JumpCond`, but unconditional
|
||||||
Jmp(usize),
|
Jmp(isize),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,10 @@ impl<'ast, 'bc, 'gc> Compiler<'ast, 'bc, 'gc> {
|
||||||
};
|
};
|
||||||
self.blocks.push(global_block);
|
self.blocks.push(global_block);
|
||||||
self.current_block = self.blocks.len() - 1;
|
self.current_block = self.blocks.len() - 1;
|
||||||
|
|
||||||
|
// padding for backwards jumps
|
||||||
|
self.push_instr(Instr::Nop, StackChange::None, Span::dummy());
|
||||||
|
|
||||||
self.compile_stmts(&ast.0)?;
|
self.compile_stmts(&ast.0)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -169,7 +173,7 @@ impl<'ast, 'bc, 'gc> Compiler<'ast, 'bc, 'gc> {
|
||||||
let block = &mut self.blocks[self.current_block];
|
let block = &mut self.blocks[self.current_block];
|
||||||
let next_index = block.code.len();
|
let next_index = block.code.len();
|
||||||
let jmp_pos = (next_index - 1) - jmp_idx;
|
let jmp_pos = (next_index - 1) - jmp_idx;
|
||||||
block.code[jmp_idx] = Instr::JumpFalse(jmp_pos);
|
block.code[jmp_idx] = Instr::JumpFalse(jmp_pos as isize);
|
||||||
|
|
||||||
match else_part {
|
match else_part {
|
||||||
ElsePart::Else(block, _) => {
|
ElsePart::Else(block, _) => {
|
||||||
|
|
@ -183,19 +187,35 @@ impl<'ast, 'bc, 'gc> Compiler<'ast, 'bc, 'gc> {
|
||||||
let block = &mut self.blocks[self.current_block];
|
let block = &mut self.blocks[self.current_block];
|
||||||
let next_index = block.code.len();
|
let next_index = block.code.len();
|
||||||
let jmp_pos = (next_index - else_skip_jmp_idx) - 1;
|
let jmp_pos = (next_index - else_skip_jmp_idx) - 1;
|
||||||
block.code[else_skip_jmp_idx] = Instr::Jmp(jmp_pos);
|
block.code[else_skip_jmp_idx] = Instr::Jmp(jmp_pos as isize);
|
||||||
} else {
|
} else {
|
||||||
let block = &mut self.blocks[self.current_block];
|
let block = &mut self.blocks[self.current_block];
|
||||||
let next_index = block.code.len();
|
let next_index = block.code.len();
|
||||||
let jmp_pos = (next_index - 1) - jmp_idx;
|
let jmp_pos = (next_index - 1) - jmp_idx;
|
||||||
block.code[jmp_idx] = Instr::JumpFalse(jmp_pos);
|
block.code[jmp_idx] = Instr::JumpFalse(jmp_pos as isize);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_loop(&mut self, _: &Block, _: Span) -> CResult<()> {
|
fn compile_loop(&mut self, ast_block: &'ast Block, span: Span) -> CResult<()> {
|
||||||
todo!()
|
/*
|
||||||
|
╭>0 // do things
|
||||||
|
╰─1 JMP (-2),
|
||||||
|
*/
|
||||||
|
|
||||||
|
let block = &self.blocks[self.current_block];
|
||||||
|
let first_stmt_idx = block.code.len() as isize;
|
||||||
|
self.compile_block(ast_block)?;
|
||||||
|
|
||||||
|
let block = &self.blocks[self.current_block];
|
||||||
|
let jmp_index = block.code.len() as isize;
|
||||||
|
|
||||||
|
let jmp_offset = -(jmp_index - first_stmt_idx + 1);
|
||||||
|
|
||||||
|
self.push_instr(Instr::Jmp(jmp_offset), StackChange::None, span);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_while(&mut self, _: &WhileStmt) -> CResult<()> {
|
fn compile_while(&mut self, _: &WhileStmt) -> CResult<()> {
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ impl<'bc> Vm<'bc, '_> {
|
||||||
|
|
||||||
fn dispatch_instr(&mut self, instr: Instr) -> VmResult {
|
fn dispatch_instr(&mut self, instr: Instr) -> VmResult {
|
||||||
match instr {
|
match instr {
|
||||||
|
Instr::Nop => {}
|
||||||
Instr::Store(index) => {
|
Instr::Store(index) => {
|
||||||
let val = self.stack.pop().unwrap();
|
let val = self.stack.pop().unwrap();
|
||||||
self.stack.insert(index, val);
|
self.stack.insert(index, val);
|
||||||
|
|
@ -153,12 +154,12 @@ impl<'bc> Vm<'bc, '_> {
|
||||||
Instr::JumpFalse(pos) => {
|
Instr::JumpFalse(pos) => {
|
||||||
let val = self.stack.pop().unwrap();
|
let val = self.stack.pop().unwrap();
|
||||||
match val {
|
match val {
|
||||||
Value::Bool(false) => self.pc += pos,
|
Value::Bool(false) => self.pc = (self.pc as isize + pos) as usize,
|
||||||
Value::Bool(true) => {}
|
Value::Bool(true) => {}
|
||||||
_ => return Err("bad type"),
|
_ => return Err("bad type"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::Jmp(pos) => self.pc += pos,
|
Instr::Jmp(pos) => self.pc = (self.pc as isize + pos) as usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
12
test.dil
12
test.dil
|
|
@ -1,11 +1,3 @@
|
||||||
let x = 5;
|
if 54 > 53 {
|
||||||
|
print "hallo conny";
|
||||||
let y = 0;
|
|
||||||
|
|
||||||
if x < 0 {
|
|
||||||
y = x;
|
|
||||||
} else {
|
|
||||||
y = "hello it is smaller";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print y;
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue