basic functions support

basic-interpreter
ondra05 2022-08-06 23:30:37 +02:00
parent f1f01ad2a5
commit 966f610040
1 changed files with 27 additions and 2 deletions

View File

@ -28,6 +28,16 @@ impl<'s> Context<'s> {
}
}
/// Execute whole function and return last value on stack (or nil)
pub fn execute(&mut self) -> Result<Value<'s>> {
let len = self.fun.bytecode.len();
while self.pc < len {
self.tick()?;
}
Ok(self.stack.pop().unwrap_or(Value::Nil))
}
/// Execute next instruction
pub fn tick(&mut self) -> Result<()> {
use Instruction::*;
@ -41,10 +51,25 @@ impl<'s> Context<'s> {
Call(n) if n >= self.stack.len() => return Err(IndexOutOfBoundsError::Stack.into()),
Call(n) => {
let fun = self.stack_pop()?;
let mut args = self.stack.split_off(self.stack.len() - n);
match fun {
Value::Function(_) => todo!("function calls"),
Value::Function(fun) => {
if fun.locals_len > args.len() {
args.resize(fun.locals_len, Value::Nil);
}
self.stack.push(
Context {
stack: vec![],
locals: args,
pc: 0,
fun,
}
.execute()?,
);
}
Value::NativeFun(NativeFun(f)) => {
let v = f(&self.stack.split_off(self.stack.len() - n));
let v = f(&args);
self.stack.push(v);
}
_ => unimplemented!("invalid function type"),