Skip to content

Commit

Permalink
Functions now work
Browse files Browse the repository at this point in the history
  • Loading branch information
Quaqqer committed Jan 17, 2024
1 parent 41bcb7e commit c1ed372
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 15 deletions.
10 changes: 5 additions & 5 deletions crates/saft-bytecode/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,11 @@ impl Compiler {
Ok((chunk, self.items.clone()))
}

fn compile_fn(&mut self, function: Spanned<&ir::Function>) -> Result<Rc<SaftFunction>, Error> {
fn compile_fn(&mut self, function: Spanned<&ir::Function>) -> Result<SaftFunction, Error> {
fn inner(
compiler: &mut Compiler,
function: Spanned<&ir::Function>,
) -> Result<Rc<SaftFunction>, Error> {
) -> Result<SaftFunction, Error> {
let Spanned { s, v: function } = function;
let ir::Function { params, body } = function;

Expand All @@ -119,10 +119,10 @@ impl Compiler {
compiler.compile_block(body, &mut chunk)?;
chunk.emit(Op::Return, s);

Ok(Rc::new(SaftFunction {
Ok(SaftFunction {
arity: params.len(),
chunk,
}))
chunk: Rc::new(chunk),
})
}

let prev_i = self.stack_i;
Expand Down
6 changes: 2 additions & 4 deletions crates/saft-bytecode/src/item.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use std::rc::Rc;

use crate::value::SaftFunction;

#[derive(Clone)]
#[derive(Clone, Debug)]
pub enum Item {
SaftFunction(Rc<SaftFunction>),
SaftFunction(SaftFunction),
}
6 changes: 3 additions & 3 deletions crates/saft-bytecode/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ pub enum Value {

#[derive(Debug, Clone)]
pub enum Function {
SaftFunction(Rc<SaftFunction>),
SaftFunction(SaftFunction),
}

#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct SaftFunction {
pub arity: usize,
pub chunk: Chunk,
pub chunk: Rc<Chunk>,
}

impl Value {
Expand Down
61 changes: 58 additions & 3 deletions crates/saft-bytecode/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,12 @@ impl Vm {
pub fn interpret_chunk(&mut self, chunk: Rc<Chunk>) -> Result<(), Error> {
self.call_stack.push(CallFrame::new(chunk, 0));

self.run()
let res = self.run();
println!(
"final stack: {:?}",
self.stack.iter().map(|v| v.repr()).collect::<Vec<_>>()
);
res
}

pub fn interpret_expr(&mut self, chunk: Rc<Chunk>) -> Result<Value, Error> {
Expand All @@ -105,6 +110,8 @@ impl Vm {
}

fn run(&mut self) -> Result<(), Error> {
// println!("{:?}", self.call_stack.last().unwrap().chunk);
// println!("{:?}", self.items);
while {
let call_frame = self.call_stack.last().unwrap();
call_frame.i < call_frame.chunk.end()
Expand All @@ -120,14 +127,27 @@ impl Vm {
}

fn eval_op(&mut self, op: &Op, s: &Span) -> Result<(), Error> {
// println!(
// "{:?}",
// self.stack.iter().map(|v| v.repr()).collect::<Vec<_>>()
// );
// println!("{:?}", op);

match op {
Op::Pop => {
self.pop();
}
Op::PopN(n) => {
self.stack.truncate(self.stack.len() - n);
}
Op::Return => todo!(),
Op::Return => {
let call_frame = self.call_stack.pop().unwrap();
let ret = self.pop();
self.stack.truncate(call_frame.stack_base);
self.push(ret);

return Ok(());
}
Op::Nil => self.push(Value::Nil),
Op::Bool(b) => self.push(Value::Num(Num::Bool(*b))),
Op::Float(f) => self.push(Value::Num(Num::Float(*f))),
Expand Down Expand Up @@ -185,7 +205,29 @@ impl Vm {
}
self.push(v);
}
Op::Call(_) => {}
Op::Call(n_args) => {
let args = self.popn(*n_args);
let fun = self.pop();

match fun {
Value::Function(Function::SaftFunction(fun)) => {
self.call_stack.last_mut().unwrap().i += 1;
self.enter_frame(fun.chunk.clone());
for arg in args {
self.push(arg);
}
}
_ => {
exotic!(
"Uncallable",
s,
format!("Value of type '{}' is not callable", fun.ty().name())
)
}
}

return Ok(());
}
Op::Index => {
let index = self.pop();
let indexable = self.pop();
Expand Down Expand Up @@ -246,6 +288,10 @@ impl Vm {
self.stack.pop().unwrap()
}

fn popn(&mut self, n: usize) -> Vec<Value> {
self.stack.split_off(self.stack.len() - n)
}

#[allow(unused)]
fn peek(&self) -> &Value {
self.stack.last().unwrap()
Expand Down Expand Up @@ -296,4 +342,13 @@ impl Vm {
pub fn get_stack(&self) -> &Vec<Value> {
&self.stack
}

fn enter_frame(&mut self, chunk: Rc<Chunk>) {
let stack_base = self.stack.len();
self.call_stack.push(CallFrame {
i: 0,
stack_base,
chunk,
})
}
}

0 comments on commit c1ed372

Please sign in to comment.