mirror of
https://github.com/Noratrieb/dilaria.git
synced 2026-01-14 17:35:03 +01:00
return try
This commit is contained in:
parent
f2bff066c6
commit
6a8eb89381
8 changed files with 86 additions and 11 deletions
|
|
@ -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")]
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
)
|
||||
})?,
|
||||
};
|
||||
|
|
|
|||
43
src/vm.rs
43
src/vm.rs
|
|
@ -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 {
|
||||
|
|
|
|||
11
test.dil
11
test.dil
|
|
@ -1,3 +1,10 @@
|
|||
fn test(uwu) {
|
||||
let owo = 5;
|
||||
fn test() {
|
||||
print "yo wtf";
|
||||
}
|
||||
|
||||
test();
|
||||
test();
|
||||
|
||||
fn uwu() {}
|
||||
|
||||
uwu();
|
||||
|
|
|
|||
|
|
@ -4,13 +4,12 @@ macro_rules! run_test {
|
|||
#[test]
|
||||
fn $name() {
|
||||
let code = $code;
|
||||
let output = _run_test(code);
|
||||
let output = crate::common::_run_test(code);
|
||||
insta::assert_debug_snapshot!(output);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn _run_test(code: &str) -> String {
|
||||
let mut stdout = Vec::<u8>::new();
|
||||
let mut cfg = dilaria::Config {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
mod common;
|
||||
use crate::common::_run_test;
|
||||
|
||||
run_test!(
|
||||
single_if,
|
||||
|
|
|
|||
25
tests/functions.rs
Normal file
25
tests/functions.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
mod common;
|
||||
|
||||
run_test!(
|
||||
single_call,
|
||||
r#"
|
||||
fn test() {
|
||||
print "correct";
|
||||
}
|
||||
|
||||
test();
|
||||
"#
|
||||
);
|
||||
|
||||
run_test!(
|
||||
single_call_expect_return,
|
||||
r#"
|
||||
fn test() {
|
||||
print "correct1";
|
||||
}
|
||||
|
||||
test();
|
||||
|
||||
print "correct2";
|
||||
"#
|
||||
);
|
||||
7
tests/snapshots/functions__single_call.snap
Normal file
7
tests/snapshots/functions__single_call.snap
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
source: tests/functions.rs
|
||||
assertion_line: 3
|
||||
expression: output
|
||||
|
||||
---
|
||||
"correct\n"
|
||||
Loading…
Add table
Add a link
Reference in a new issue