feat: partial func (WIP)
This commit is contained in:
38
Cargo.lock
generated
38
Cargo.lock
generated
@@ -328,6 +328,7 @@ dependencies = [
|
|||||||
"rnix",
|
"rnix",
|
||||||
"rustyline",
|
"rustyline",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -336,6 +337,12 @@ version = "1.21.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-lite"
|
||||||
|
version = "0.2.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "priority-queue"
|
name = "priority-queue"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@@ -554,6 +561,37 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing"
|
||||||
|
version = "0.1.41"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
|
||||||
|
dependencies = [
|
||||||
|
"pin-project-lite",
|
||||||
|
"tracing-attributes",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-attributes"
|
||||||
|
version = "0.1.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-core"
|
||||||
|
version = "0.1.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.18"
|
version = "1.0.18"
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ hashbrown = "0.15"
|
|||||||
priority-queue = "2.5"
|
priority-queue = "2.5"
|
||||||
lru = "0.14"
|
lru = "0.14"
|
||||||
replace_with = "0.1"
|
replace_with = "0.1"
|
||||||
|
tracing = "0.1"
|
||||||
inkwell = { version = "0.6.0", features = ["llvm18-1"] }
|
inkwell = { version = "0.6.0", features = ["llvm18-1"] }
|
||||||
|
|
||||||
rustyline = { version = "15.0", optional = true }
|
rustyline = { version = "15.0", optional = true }
|
||||||
|
|||||||
11
src/env.rs
11
src/env.rs
@@ -4,7 +4,7 @@ use std::rc::{Rc, Weak};
|
|||||||
use ecow::EcoString;
|
use ecow::EcoString;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
|
||||||
use crate::error::{Error, Result};
|
use crate::error::Result;
|
||||||
use crate::stack::Stack;
|
use crate::stack::Stack;
|
||||||
use crate::ty::internal::Value;
|
use crate::ty::internal::Value;
|
||||||
|
|
||||||
@@ -48,15 +48,14 @@ impl Env {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enter_cache_level<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
|
pub fn enter_cache_level<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> (T, HashMap<usize, Value>) {
|
||||||
self.cache.push(HashMap::new());
|
self.cache.push(HashMap::new());
|
||||||
let ret = f(self);
|
let ret = f(self);
|
||||||
self.cache.pop();
|
(ret, self.cache.pop().unwrap())
|
||||||
ret
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop_cache_level(&mut self) {
|
pub fn pop_cache_level(&mut self) -> HashMap<usize, Value> {
|
||||||
self.cache.pop();
|
self.cache.pop().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_cache(&mut self, idx: usize, val: Value) {
|
pub fn insert_cache(&mut self, idx: usize, val: Value) {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use tracing::{event, span, Level};
|
||||||
use derive_more::Unwrap;
|
use derive_more::Unwrap;
|
||||||
use ecow::EcoString;
|
use ecow::EcoString;
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
@@ -170,14 +171,14 @@ impl DowngradeContext {
|
|||||||
|
|
||||||
pub fn new_dep(&mut self, this: Index, dep: Dep) -> Result<()> {
|
pub fn new_dep(&mut self, this: Index, dep: Dep) -> Result<()> {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
println!("{this:?} => {dep:?}");
|
event!(Level::DEBUG, "{this:?} => {dep:?}");
|
||||||
match this {
|
match this {
|
||||||
Index::Thunk(idx) => {
|
Index::Thunk(idx) => {
|
||||||
if dep == Dep::Thunk(idx) && !matches!(self.thunks[idx].0, Ir::List(_)) {
|
/* if dep == Dep::Thunk(idx) && !matches!(self.thunks[idx].0, Ir::List(_)) {
|
||||||
return Err(Error::DowngradeError(
|
return Err(Error::DowngradeError(
|
||||||
"infinite recursion encountered".into(),
|
"infinite recursion encountered".into(),
|
||||||
));
|
));
|
||||||
}
|
} */
|
||||||
self.thunk_deps[idx].insert(dep.unwrap_thunk())
|
self.thunk_deps[idx].insert(dep.unwrap_thunk())
|
||||||
}
|
}
|
||||||
Index::Func(idx) => self.func_deps[idx].insert(dep),
|
Index::Func(idx) => self.func_deps[idx].insert(dep),
|
||||||
|
|||||||
@@ -1,21 +1,16 @@
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use derive_more::Constructor;
|
||||||
|
use hashbrown::HashMap;
|
||||||
|
|
||||||
use crate::env::Env;
|
use crate::env::Env;
|
||||||
|
|
||||||
use crate::ir;
|
use crate::ir;
|
||||||
pub struct Func<'gc> {
|
|
||||||
pub func: &'gc ir::Func,
|
|
||||||
pub env: Rc<Env>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'gc> Func<'gc> {
|
use super::Value;
|
||||||
pub fn new(func: &'gc ir::Func, env: Rc<Env>) -> Self {
|
|
||||||
Self { func, env }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq for Func<'_> {
|
#[derive(Debug, Clone, Constructor)]
|
||||||
fn eq(&self, _: &Self) -> bool {
|
pub struct PartialFunc {
|
||||||
false
|
pub idx: usize,
|
||||||
}
|
pub args: Vec<Value>,
|
||||||
|
pub cache: HashMap<usize, Value>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
use derive_more::{IsVariant, Unwrap};
|
use derive_more::{IsVariant, Unwrap};
|
||||||
use ecow::EcoString;
|
use ecow::EcoString;
|
||||||
|
use func::PartialFunc;
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
use replace_with::replace_with_or_abort;
|
use replace_with::replace_with_or_abort;
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ pub enum Value {
|
|||||||
PrimOp(Rc<PrimOp>),
|
PrimOp(Rc<PrimOp>),
|
||||||
PartialPrimOp(Rc<PartialPrimOp>),
|
PartialPrimOp(Rc<PartialPrimOp>),
|
||||||
Func(usize),
|
Func(usize),
|
||||||
PartialFunc(usize, Vec<Value>),
|
PartialFunc(Rc<PartialFunc>)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hash for Value {
|
impl Hash for Value {
|
||||||
@@ -97,7 +98,7 @@ pub enum ValueAsRef<'v> {
|
|||||||
PrimOp(&'v PrimOp),
|
PrimOp(&'v PrimOp),
|
||||||
PartialPrimOp(&'v PartialPrimOp),
|
PartialPrimOp(&'v PartialPrimOp),
|
||||||
Func(usize),
|
Func(usize),
|
||||||
PartialFunc(usize, &'v Vec<Value>),
|
PartialFunc(&'v PartialFunc),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Value {
|
impl Value {
|
||||||
@@ -117,7 +118,7 @@ impl Value {
|
|||||||
PrimOp(x) => R::PrimOp(x),
|
PrimOp(x) => R::PrimOp(x),
|
||||||
PartialPrimOp(x) => R::PartialPrimOp(x),
|
PartialPrimOp(x) => R::PartialPrimOp(x),
|
||||||
Func(x) => R::Func(*x),
|
Func(x) => R::Func(*x),
|
||||||
PartialFunc(x, args) => R::PartialFunc(*x, args),
|
PartialFunc(x) => R::PartialFunc(x),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,14 +165,15 @@ impl Value {
|
|||||||
*self = match self {
|
*self = match self {
|
||||||
PrimOp(func) => func.call(args, engine),
|
PrimOp(func) => func.call(args, engine),
|
||||||
PartialPrimOp(func) => func.call(args, engine),
|
PartialPrimOp(func) => func.call(args, engine),
|
||||||
PartialFunc(idx, old) => {
|
PartialFunc(func) => {
|
||||||
|
let self::PartialFunc { idx, args: old_args, cache } = Rc::make_mut(func);
|
||||||
let idx = *idx;
|
let idx = *idx;
|
||||||
let len = args.len() + old.len();
|
let len = args.len() + old_args.len();
|
||||||
env.reserve_args(len);
|
env.reserve_args(len);
|
||||||
env.enter_args(std::mem::take(old));
|
env.enter_args(std::mem::take(old_args));
|
||||||
env.enter_cache_level(|env| {
|
|
||||||
let mut args = args.into_iter().peekable();
|
let mut args = args.into_iter().peekable();
|
||||||
env.enter_arg(args.next().unwrap());
|
env.enter_arg(args.next().unwrap());
|
||||||
|
let (ret, cache) = env.enter_cache_level(|env| {
|
||||||
let mut ret = engine.eval_thunk(idx, env)?;
|
let mut ret = engine.eval_thunk(idx, env)?;
|
||||||
while args.peek().is_some() {
|
while args.peek().is_some() {
|
||||||
match ret {
|
match ret {
|
||||||
@@ -190,22 +192,24 @@ impl Value {
|
|||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ret.ok()
|
||||||
|
});
|
||||||
|
let mut ret = ret?;
|
||||||
let args = env.pop_args(len);
|
let args = env.pop_args(len);
|
||||||
if let Value::Func(idx) = ret {
|
if let Value::Func(idx) = ret {
|
||||||
ret = Value::PartialFunc(idx, args)
|
ret = PartialFunc(self::PartialFunc::new(idx, args, cache).into());
|
||||||
} else if let Value::PartialFunc(_, old) = &mut ret {
|
} else if let Value::PartialFunc(func) = &mut ret {
|
||||||
old.extend(args);
|
Rc::make_mut(func).args.extend(args);
|
||||||
}
|
}
|
||||||
ret.ok()
|
ret.ok()
|
||||||
})
|
|
||||||
}
|
}
|
||||||
&mut Func(idx) => {
|
&mut Func(idx) => {
|
||||||
let len = args.len();
|
let len = args.len();
|
||||||
let mut args = args.into_iter().peekable();
|
let mut args = args.into_iter().peekable();
|
||||||
env.reserve_args(len);
|
env.reserve_args(len);
|
||||||
env.enter_cache_level(|env| {
|
let (ret, cache) = env.enter_cache_level(|env| {
|
||||||
env.enter_arg(args.next().unwrap());
|
|
||||||
let mut ret = engine.eval_thunk(idx, env)?;
|
let mut ret = engine.eval_thunk(idx, env)?;
|
||||||
|
env.enter_arg(args.next().unwrap());
|
||||||
while args.peek().is_some() {
|
while args.peek().is_some() {
|
||||||
match ret {
|
match ret {
|
||||||
Value::Func(func) => {
|
Value::Func(func) => {
|
||||||
@@ -223,14 +227,16 @@ impl Value {
|
|||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ret.ok()
|
||||||
|
});
|
||||||
|
let mut ret = ret?;
|
||||||
let args = env.pop_args(len);
|
let args = env.pop_args(len);
|
||||||
if let Value::Func(idx) = ret {
|
if let Value::Func(idx) = ret {
|
||||||
ret = Value::PartialFunc(idx, args)
|
ret = Value::PartialFunc(self::PartialFunc::new(idx, args, cache).into())
|
||||||
} else if let Value::PartialFunc(_, old) = &mut ret {
|
} else if let Value::PartialFunc(func) = &mut ret {
|
||||||
old.extend(args);
|
Rc::make_mut(func).args.extend(args);
|
||||||
}
|
}
|
||||||
ret.ok()
|
ret.ok()
|
||||||
})
|
|
||||||
}
|
}
|
||||||
Catchable(_) => return Ok(()),
|
Catchable(_) => return Ok(()),
|
||||||
other => todo!("{}", other.typename()),
|
other => todo!("{}", other.typename()),
|
||||||
|
|||||||
Reference in New Issue
Block a user