mirror of
https://github.com/Noratrieb/dilaria.git
synced 2026-01-17 02:45:02 +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.
|
/// used if there are errors.
|
||||||
pub spans: Vec<'bc, Span>,
|
pub spans: Vec<'bc, Span>,
|
||||||
/// How many parameters the function accepts.
|
/// 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")]
|
#[cfg(feature = "_debug")]
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ impl<'bc, 'gc> Compiler<'bc, 'gc> {
|
||||||
decl.params[u8::MAX as usize]
|
decl.params[u8::MAX as usize]
|
||||||
.span
|
.span
|
||||||
.extend(decl.params.last().unwrap().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)?,
|
Some(&instr) => self.dispatch_instr(instr)?,
|
||||||
None => return Ok(()),
|
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;
|
self.pc += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -189,7 +189,7 @@ impl<'bc> Vm<'bc, '_> {
|
||||||
Instr::Jmp(pos) => self.pc = (self.pc as isize + pos) as usize,
|
Instr::Jmp(pos) => self.pc = (self.pc as isize + pos) as usize,
|
||||||
Instr::Call => self.call()?,
|
Instr::Call => self.call()?,
|
||||||
// todo implement
|
// todo implement
|
||||||
Instr::Return => return Ok(()),
|
Instr::Return => self.ret()?,
|
||||||
Instr::ShrinkStack(size) => {
|
Instr::ShrinkStack(size) => {
|
||||||
assert!(self.stack.len() >= size);
|
assert!(self.stack.len() >= size);
|
||||||
let new_len = 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 {
|
if let Value::Function(func) = function {
|
||||||
let fn_block = &self.blocks[func];
|
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_offset = new_stack_frame_start;
|
||||||
|
|
||||||
self.stack.push(Value::NativeU(old_offset));
|
self.stack.push(Value::NativeU(old_offset));
|
||||||
|
|
@ -241,6 +241,23 @@ impl<'bc> Vm<'bc, '_> {
|
||||||
Ok(())
|
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 {
|
fn type_error(&self) -> VmError {
|
||||||
"bad type".into()
|
"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 {
|
impl Display for Value {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
||||||
13
test.dil
13
test.dil
|
|
@ -1,3 +1,10 @@
|
||||||
fn test(uwu) {
|
fn test() {
|
||||||
let owo = 5;
|
print "yo wtf";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test();
|
||||||
|
test();
|
||||||
|
|
||||||
|
fn uwu() {}
|
||||||
|
|
||||||
|
uwu();
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,12 @@ macro_rules! run_test {
|
||||||
#[test]
|
#[test]
|
||||||
fn $name() {
|
fn $name() {
|
||||||
let code = $code;
|
let code = $code;
|
||||||
let output = _run_test(code);
|
let output = crate::common::_run_test(code);
|
||||||
insta::assert_debug_snapshot!(output);
|
insta::assert_debug_snapshot!(output);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn _run_test(code: &str) -> String {
|
pub fn _run_test(code: &str) -> String {
|
||||||
let mut stdout = Vec::<u8>::new();
|
let mut stdout = Vec::<u8>::new();
|
||||||
let mut cfg = dilaria::Config {
|
let mut cfg = dilaria::Config {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
mod common;
|
mod common;
|
||||||
use crate::common::_run_test;
|
|
||||||
|
|
||||||
run_test!(
|
run_test!(
|
||||||
single_if,
|
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