first draft of partial application, is working in easy cases
This commit is contained in:
parent
dee9bcfc33
commit
f8adaa7971
|
@ -76,7 +76,9 @@ pub fn run(src: &'static str) {
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
env::set_var("RUST_BACKTRACE", "1");
|
env::set_var("RUST_BACKTRACE", "1");
|
||||||
let src = "
|
let src = "
|
||||||
|
fn add2 (x, y) -> add (x, y)
|
||||||
|
|
||||||
|
add2 (_, 2) (2)
|
||||||
|
|
||||||
";
|
";
|
||||||
run(src);
|
run(src);
|
||||||
|
|
|
@ -203,7 +203,7 @@ impl fmt::Display for Ast {
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join("\n")
|
.join("\n")
|
||||||
),
|
),
|
||||||
Placeholder => todo!(),
|
Placeholder => write!(f, "Placeholder"),
|
||||||
LBox(_name, _rhs) => todo!(),
|
LBox(_name, _rhs) => todo!(),
|
||||||
Match(value, clauses) => {
|
Match(value, clauses) => {
|
||||||
write!(
|
write!(
|
||||||
|
|
|
@ -52,6 +52,7 @@ impl LFn {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn chunk(&self, arity: u8) -> &Chunk {
|
pub fn chunk(&self, arity: u8) -> &Chunk {
|
||||||
|
// println!("Getting chunk of {arity} from {:?}", self);
|
||||||
match self {
|
match self {
|
||||||
LFn::Declared { .. } => unreachable!(),
|
LFn::Declared { .. } => unreachable!(),
|
||||||
LFn::Defined { chunks, .. } => &chunks.iter().find(|(a, _)| *a == arity).unwrap().1,
|
LFn::Defined { chunks, .. } => &chunks.iter().find(|(a, _)| *a == arity).unwrap().1,
|
||||||
|
@ -68,9 +69,9 @@ impl LFn {
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Partial {
|
pub struct Partial {
|
||||||
args: Vec<Value>,
|
pub args: Vec<Value>,
|
||||||
name: &'static str,
|
pub name: &'static str,
|
||||||
function: Value,
|
pub function: Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
44
src/vm.rs
44
src/vm.rs
|
@ -2,7 +2,7 @@ use crate::base::BaseFn;
|
||||||
use crate::compiler::{Chunk, Op};
|
use crate::compiler::{Chunk, Op};
|
||||||
use crate::parser::Ast;
|
use crate::parser::Ast;
|
||||||
use crate::spans::Spanned;
|
use crate::spans::Spanned;
|
||||||
use crate::value::{LFn, Value};
|
use crate::value::{LFn, Partial, Value};
|
||||||
use chumsky::prelude::SimpleSpan;
|
use chumsky::prelude::SimpleSpan;
|
||||||
use imbl::{HashMap, Vector};
|
use imbl::{HashMap, Vector};
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
|
@ -705,7 +705,19 @@ impl Vm {
|
||||||
self.ip += 1;
|
self.ip += 1;
|
||||||
}
|
}
|
||||||
Partial => {
|
Partial => {
|
||||||
todo!();
|
let arity = self.chunk().bytecode[self.ip + 1];
|
||||||
|
self.ip += 2;
|
||||||
|
let the_fn = self.pop();
|
||||||
|
let Value::Fn(ref inner) = the_fn else {
|
||||||
|
return self.panic("only functions may be partially applied");
|
||||||
|
};
|
||||||
|
let args = self.stack.split_off(self.stack.len() - arity as usize);
|
||||||
|
let partial = crate::value::Partial {
|
||||||
|
args,
|
||||||
|
name: inner.name(),
|
||||||
|
function: the_fn,
|
||||||
|
};
|
||||||
|
self.push(Value::Partial(Rc::new(partial)));
|
||||||
}
|
}
|
||||||
Call => {
|
Call => {
|
||||||
let arity = self.chunk().bytecode[self.ip + 1];
|
let arity = self.chunk().bytecode[self.ip + 1];
|
||||||
|
@ -742,6 +754,34 @@ impl Vm {
|
||||||
};
|
};
|
||||||
self.push(value);
|
self.push(value);
|
||||||
}
|
}
|
||||||
|
Value::Partial(partial) => {
|
||||||
|
let last_arg = self.pop();
|
||||||
|
let args = &partial.args;
|
||||||
|
for arg in args {
|
||||||
|
if *arg == Value::Nothing {
|
||||||
|
self.push(last_arg.clone());
|
||||||
|
} else {
|
||||||
|
self.push(arg.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let the_fn = partial.function.clone();
|
||||||
|
let mut frame = CallFrame {
|
||||||
|
function: the_fn,
|
||||||
|
arity: args.len() as u8,
|
||||||
|
stack_base: self.stack.len() - arity as usize - 1,
|
||||||
|
ip: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
swap(&mut self.frame, &mut frame);
|
||||||
|
frame.ip = self.ip;
|
||||||
|
|
||||||
|
self.call_stack.push(frame);
|
||||||
|
self.ip = 0;
|
||||||
|
|
||||||
|
if crate::DEBUG_RUN {
|
||||||
|
println!("== calling into {} ==", self.frame.function.show());
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => return self.panic_with(format!("{} is not a function", val.show())),
|
_ => return self.panic_with(format!("{} is not a function", val.show())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user