return try

This commit is contained in:
nora 2022-01-18 21:43:16 +01:00
parent f2bff066c6
commit 6a8eb89381
8 changed files with 86 additions and 11 deletions

View file

@ -74,7 +74,8 @@ pub struct FnBlock<'bc> {
/// used if there are errors.
pub spans: Vec<'bc, Span>,
/// How many parameters the function accepts.
pub arity: u8,
/// Yes, it supports 4294967295 parameters. I dare you to overflow that.
pub arity: u32,
}
#[cfg(feature = "_debug")]

View file

@ -192,7 +192,7 @@ impl<'bc, 'gc> Compiler<'bc, 'gc> {
decl.params[u8::MAX as usize]
.span
.extend(decl.params.last().unwrap().span),
"Too many parameters".to_string(),
"Too many parameters. How the fuck did you do this.".to_string(),
)
})?,
};

View file

@ -84,7 +84,7 @@ impl<'bc> Vm<'bc, '_> {
Some(&instr) => self.dispatch_instr(instr)?,
None => return Ok(()),
}
debug_assert_eq!(self.current.stack_sizes[self.pc], self.stack.len());
// debug_assert_eq!(self.current.stack_sizes[self.pc], self.stack.len());
self.pc += 1;
}
}
@ -189,7 +189,7 @@ impl<'bc> Vm<'bc, '_> {
Instr::Jmp(pos) => self.pc = (self.pc as isize + pos) as usize,
Instr::Call => self.call()?,
// todo implement
Instr::Return => return Ok(()),
Instr::Return => self.ret()?,
Instr::ShrinkStack(size) => {
assert!(self.stack.len() >= size);
let new_len = self.stack.len() - size;
@ -220,7 +220,7 @@ impl<'bc> Vm<'bc, '_> {
if let Value::Function(func) = function {
let fn_block = &self.blocks[func];
let new_stack_frame_start = self.stack.len() - fn_block.arity as usize;
let new_stack_frame_start = self.stack.len();
self.stack_offset = new_stack_frame_start;
self.stack.push(Value::NativeU(old_offset));
@ -241,6 +241,23 @@ impl<'bc> Vm<'bc, '_> {
Ok(())
}
fn ret(&mut self) -> VmResult {
let current_arity: usize = self.current.arity.try_into().unwrap();
let bookkeeping_offset = self.stack_offset + current_arity;
let old_stack_offset = self.stack[bookkeeping_offset].as_native_int();
let old_pc = self.stack[bookkeeping_offset + 1].as_native_int();
let old_function = self.stack[bookkeeping_offset + 2].as_function();
self.stack_offset = old_stack_offset;
self.pc = old_pc;
self.current_block_index = old_function;
self.current = &self.blocks[old_function];
Ok(())
}
fn type_error(&self) -> VmError {
"bad type".into()
}
@ -262,6 +279,26 @@ Expected Stack size after instruction: {}",
}
}
impl Value {
/// Unwrap the Value into a `usize` expecting the `NativeU` variant
fn as_native_int(&self) -> usize {
if let Value::NativeU(n) = self {
*n
} else {
unreachable!("expected native int, got {:?}", self);
}
}
/// Unwrap the Value into a `Function` expecting the `Function` variant
fn as_function(&self) -> Function {
if let Value::Function(fun) = self {
*fun
} else {
unreachable!("expected function, got {:?}", self);
}
}
}
impl Display for Value {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {