The big exponential thing was ironically Hash which was being called for memo which existed to prevent exponential behavior. Reimplmenented the caching hash, and much much faster. Still some failing tests, and bvau might be looping

This commit is contained in:
2023-04-04 23:40:09 -04:00
parent 8ccdfd8ab2
commit a06c5854c8
3 changed files with 140 additions and 105 deletions

View File

@@ -98,7 +98,8 @@
#wasm3 #wasm3
clang cmake clang cmake
(rust-bin.stable.latest.default.override { targets = [ "wasm32-wasi" ]; }) cargo cargo-flamegraph
#(rust-bin.stable.latest.default.override { targets = [ "wasm32-wasi" ]; })
#stack (haskellPackages.ghcWithPackages (p: [p.parallel])) #stack (haskellPackages.ghcWithPackages (p: [p.parallel]))
koka koka
pkgs_old.emscripten pkgs_old.emscripten

View File

@@ -6,6 +6,10 @@ build = "build.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[profile.bench]
debug = true
[dependencies] [dependencies]
lalrpop-util = {version="0.19.7", features=["lexer"]} lalrpop-util = {version="0.19.7", features=["lexer"]}
regex = "1" regex = "1"

View File

@@ -267,7 +267,7 @@ impl DCtx {
let mut real_set = (*self.real_set).clone(); let mut real_set = (*self.real_set).clone();
let mut fake_set = (*self.fake_set).clone(); let mut fake_set = (*self.fake_set).clone();
if self.fake_if_set.contains(&id) { if self.fake_if_set.contains(&id) {
println!("Fake if real rec stopper"); //println!("Fake if real rec stopper");
return PushFrameResult::UnderIf(id); return PushFrameResult::UnderIf(id);
} }
if (e.is_some() && prms.is_some()) { if (e.is_some() && prms.is_some()) {
@@ -276,7 +276,7 @@ impl DCtx {
//fake_set.remove(&id); //fake_set.remove(&id);
} else { } else {
if fake_set.contains(&id) { if fake_set.contains(&id) {
println!("Fake body rec stopper"); //println!("Fake body rec stopper");
return PushFrameResult::UnderBody(id.clone()); return PushFrameResult::UnderBody(id.clone());
} }
fake_set.insert(id.clone()); fake_set.insert(id.clone());
@@ -288,7 +288,7 @@ impl DCtx {
e e
} else { } else {
Rc::make_mut(&mut sus_env_stack).remove(&id); Rc::make_mut(&mut sus_env_stack).remove(&id);
Rc::new(MarkedForm::SuspendedEnvLookup { name: Some(de.clone()), id: id.clone() }) MarkedForm::new_suspended_env_lookup(Some(de.clone()), id.clone())
}; };
massoc(de, de_val, Rc::clone(se)) massoc(de, de_val, Rc::clone(se))
} else { Rc::clone(se) }; } else { Rc::clone(se) };
@@ -299,7 +299,7 @@ impl DCtx {
prms prms
} else { } else {
Rc::make_mut(&mut sus_prm_stack).remove(&id); Rc::make_mut(&mut sus_prm_stack).remove(&id);
Rc::new(MarkedForm::SuspendedParamLookup { name: Some(p.clone()), id: id.clone(), cdr_num: 0, car: false, evaled: false }) MarkedForm::new_suspended_param_lookup(Some(p.clone()), id.clone(), 0, false, false)
}; };
massoc(p, p_val, inner_env) massoc(p, p_val, inner_env)
} else { inner_env }; } else { inner_env };
@@ -329,39 +329,70 @@ pub fn new_base_ctxs() -> (BCtx,DCtx) {
(bctx, DCtx { e: root_env, current_id: None, sus_env_stack: Rc::new(BTreeMap::new()), sus_prm_stack: Rc::new(BTreeMap::new()), (bctx, DCtx { e: root_env, current_id: None, sus_env_stack: Rc::new(BTreeMap::new()), sus_prm_stack: Rc::new(BTreeMap::new()),
real_set: Rc::new(BTreeSet::new()), fake_set: Rc::new(BTreeSet::new()), fake_if_set: Rc::new(BTreeSet::new()), ident: 0 } ) real_set: Rc::new(BTreeSet::new()), fake_set: Rc::new(BTreeSet::new()), fake_if_set: Rc::new(BTreeSet::new()), ident: 0 } )
} }
impl Hash for MarkedForm {
fn hash<H: Hasher>(&self, state: &mut H) {
match self {
MarkedForm::Nil => { "Nil".hash(state); },
MarkedForm::Int(i) => { "Int".hash(state); i.hash(state); },
MarkedForm::Bool(b) => { "Bool".hash(state); b.hash(state); },
MarkedForm::Symbol(s) => { "Symbol".hash(state); s.hash(state); },
#[derive(Debug, Clone, Eq, PartialEq, Hash)] MarkedForm::Pair(hash, ids, car, cdr) => { hash.hash(state); },
MarkedForm::SuspendedSymbol(hash, env, name) => { hash.hash(state); },
MarkedForm::SuspendedParamLookup { hash, .. } => { hash.hash(state); },
MarkedForm::SuspendedEnvLookup { hash, .. } => { hash.hash(state); },
MarkedForm::SuspendedPair { hash, .. } => { hash.hash(state); },
MarkedForm::SuspendedEnvEval { hash, .. } => { hash.hash(state); },
MarkedForm::SuspendedIf { hash, .. } => { hash.hash(state); },
MarkedForm::DeriComb { hash, .. } => { hash.hash(state); },
MarkedForm::PrimComb { name, .. } => { "PrimComb".hash(state); name.hash(state); },
}
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum MarkedForm { pub enum MarkedForm {
Nil, Nil,
Int(i32), Int(i32),
Bool(bool), Bool(bool),
Symbol(String), Symbol(String),
Pair(NeededIds, Rc<MarkedForm>,Rc<MarkedForm>), Pair(u64, NeededIds, Rc<MarkedForm>, Rc<MarkedForm>),
SuspendedSymbol(Option<Rc<MarkedForm>>, String), // Needs IDs if Env chains into suspended SuspendedSymbol(u64, Option<Rc<MarkedForm>>, String), // Needs IDs if Env chains into suspended
SuspendedParamLookup { name: Option<String>, id: EnvID, cdr_num: i32, car: bool, evaled: bool }, SuspendedParamLookup { hash: u64, name: Option<String>, id: EnvID, cdr_num: i32, car: bool, evaled: bool },
SuspendedEnvLookup { name: Option<String>, id: EnvID }, SuspendedEnvLookup { hash: u64, name: Option<String>, id: EnvID },
SuspendedPair { ids: NeededIds, env: Option<Rc<MarkedForm>>, car: Rc<MarkedForm>, cdr: Rc<MarkedForm>}, SuspendedPair { hash: u64, ids: NeededIds, env: Option<Rc<MarkedForm>>, car: Rc<MarkedForm>, cdr: Rc<MarkedForm>},
SuspendedEnvEval { ids: NeededIds, x: Rc<MarkedForm>, e: Rc<MarkedForm> }, SuspendedEnvEval { hash: u64, ids: NeededIds, x: Rc<MarkedForm>, e: Rc<MarkedForm> },
SuspendedIf { ids: NeededIds, env: Option<Rc<MarkedForm>>, c: Rc<MarkedForm>, t: Rc<MarkedForm>, e: Rc<MarkedForm> }, SuspendedIf { hash: u64, ids: NeededIds, env: Option<Rc<MarkedForm>>, c: Rc<MarkedForm>, t: Rc<MarkedForm>, e: Rc<MarkedForm> },
PrimComb { name: String, nonval_ok: bool, takes_de: bool, wrap_level: i32, f: fn(BCtx,DCtx,Rc<MarkedForm>) -> Result<(BCtx,Rc<MarkedForm>)> }, PrimComb { name: String, nonval_ok: bool, takes_de: bool, wrap_level: i32, f: fn(BCtx,DCtx,Rc<MarkedForm>) -> Result<(BCtx,Rc<MarkedForm>)> },
DeriComb { lookup_name: Option<String>, ids: NeededIds, se: Rc<MarkedForm>, de: Option<String>, id: EnvID, wrap_level: i32, DeriComb { hash: u64, lookup_name: Option<String>, ids: NeededIds, se: Rc<MarkedForm>, de: Option<String>, id: EnvID, wrap_level: i32,
sequence_params: Vec<String>, rest_params: Option<String>, body: Rc<MarkedForm> }, sequence_params: Vec<String>, rest_params: Option<String>, body: Rc<MarkedForm> },
} }
impl MarkedForm { impl MarkedForm {
pub fn new_suspended_symbol(e: Option<Rc<MarkedForm>>, name: String) -> Rc<MarkedForm> {
Rc::new(MarkedForm::SuspendedSymbol(calculate_hash(&("SuspendedSymbol", &e, &name)), e, name))
}
pub fn new_suspended_param_lookup(name: Option<String>, id: EnvID, cdr_num: i32, car: bool, evaled: bool) -> Rc<MarkedForm> {
Rc::new(MarkedForm::SuspendedParamLookup { hash: calculate_hash(&("SuspendedParamLookup", &name, &id, &cdr_num, &car, &evaled)), name, id, cdr_num, car, evaled })
}
pub fn new_suspended_env_lookup(name: Option<String>, id: EnvID) -> Rc<MarkedForm> {
Rc::new(MarkedForm::SuspendedEnvLookup { hash: calculate_hash(&("SuspendedEnvLookup", &name, &id)), name, id })
}
pub fn new_suspended_if(ids: NeededIds, env: Option<Rc<MarkedForm>>, c: Rc<MarkedForm>, t: Rc<MarkedForm>, e: Rc<MarkedForm>) -> Rc<MarkedForm> {
Rc::new(MarkedForm::SuspendedIf { hash: calculate_hash(&("SuspendedIf", &ids, &env, &c, &t, &e)), ids, env, c, t, e })
}
pub fn new_suspended_env_eval(x: Rc<MarkedForm>, e: Rc<MarkedForm>) -> Rc<MarkedForm> { pub fn new_suspended_env_eval(x: Rc<MarkedForm>, e: Rc<MarkedForm>) -> Rc<MarkedForm> {
let ids = if e.is_legal_env_chain().unwrap_or(true) { let ids = if e.is_legal_env_chain().unwrap_or(true) {
e.ids().union(&x.ids()) e.ids().union(&x.ids())
} else { } else {
e.ids().union_into_tail(&x.ids(), Some(&true_id)) e.ids().union_into_tail(&x.ids(), Some(&true_id))
}; };
Rc::new(MarkedForm::SuspendedEnvEval { ids, x, e }) Rc::new(MarkedForm::SuspendedEnvEval { hash: calculate_hash(&("SuspendedEnvEval", &ids, &x, &e)), ids, x, e })
} }
pub fn new_pair(car: Rc<MarkedForm>, cdr: Rc<MarkedForm>) -> Rc<MarkedForm> { pub fn new_pair(car: Rc<MarkedForm>, cdr: Rc<MarkedForm>) -> Rc<MarkedForm> {
let new_ids = car.ids().union(&cdr.ids()); let new_ids = car.ids().union(&cdr.ids());
Rc::new(MarkedForm::Pair(new_ids, car, cdr)) Rc::new(MarkedForm::Pair(calculate_hash(&("SuspendedPair", &car, &cdr)), new_ids, car, cdr))
} }
pub fn new_suspended_pair(env: Option<Rc<MarkedForm>>, attempted: Option<NeededIds>, car: Rc<MarkedForm>, cdr: Rc<MarkedForm>, under_if: Option<EnvID>) -> Rc<MarkedForm> { pub fn new_suspended_pair(env: Option<Rc<MarkedForm>>, attempted: Option<NeededIds>, car: Rc<MarkedForm>, cdr: Rc<MarkedForm>, under_if: Option<EnvID>) -> Rc<MarkedForm> {
// differentiate between call and if rec_under // differentiate between call and if rec_under
@@ -375,7 +406,11 @@ impl MarkedForm {
let ids = if let Some(rec_under) = under_if { ids.add_if_under(rec_under) } else { ids }; let ids = if let Some(rec_under) = under_if { ids.add_if_under(rec_under) } else { ids };
let ids = if let Some(env) =&env { ids.union(&env.ids()) } else { ids }; let ids = if let Some(env) =&env { ids.union(&env.ids()) } else { ids };
Rc::new(MarkedForm::SuspendedPair{ ids, env, car, cdr }) Rc::new(MarkedForm::SuspendedPair{ hash: calculate_hash(&("SuspendedPair", &ids, &env, &car, &cdr)), ids, env, car, cdr })
}
fn new_raw_deri_comb(lookup_name: Option<String>, ids: NeededIds, se: Rc<MarkedForm>, de: Option<String>, id: EnvID, wrap_level: i32,
sequence_params: Vec<String>, rest_params: Option<String>, body: Rc<MarkedForm>) -> Rc<MarkedForm> {
Rc::new(MarkedForm::DeriComb { hash: calculate_hash(&("DeriComb", &lookup_name, &ids, &se, &de, &id, &wrap_level, &sequence_params, &rest_params, &body)), lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body })
} }
pub fn new_deri_comb(se: Rc<MarkedForm>, lookup_name: Option<String>, de: Option<String>, id: EnvID, wrap_level: i32, sequence_params: Vec<String>, rest_params: Option<String>, body: Rc<MarkedForm>, rec_under: Option<EnvID>) -> Rc<MarkedForm> { pub fn new_deri_comb(se: Rc<MarkedForm>, lookup_name: Option<String>, de: Option<String>, id: EnvID, wrap_level: i32, sequence_params: Vec<String>, rest_params: Option<String>, body: Rc<MarkedForm>, rec_under: Option<EnvID>) -> Rc<MarkedForm> {
let ids = se.ids().union_without(&body.ids(), &id); let ids = se.ids().union_without(&body.ids(), &id);
@@ -384,13 +419,13 @@ impl MarkedForm {
} else { } else {
ids ids
}; };
Rc::new(MarkedForm::DeriComb{ lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body }) MarkedForm::new_raw_deri_comb(lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body)
} }
pub fn tag_name(self: &Rc<MarkedForm>, new_name: &str) -> Rc<MarkedForm> { pub fn tag_name(self: &Rc<MarkedForm>, new_name: &str) -> Rc<MarkedForm> {
match &**self { match &**self {
MarkedForm::DeriComb { lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body } => MarkedForm::DeriComb { hash, lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body } =>
Rc::new(MarkedForm::DeriComb { lookup_name: Some(new_name.to_owned()), ids: ids.clone(), se: Rc::clone(se), de: de.clone(), id: id.clone(), wrap_level: *wrap_level, sequence_params: sequence_params.clone(), rest_params: rest_params.clone(), body: Rc::clone(body) }), MarkedForm::new_raw_deri_comb(Some(new_name.to_owned()), ids.clone(), se.clone(), de.clone(), id.clone(), *wrap_level, sequence_params.clone(), rest_params.clone(), Rc::clone(body)),
MarkedForm::SuspendedParamLookup { name, id, cdr_num, car, evaled } => Rc::new(MarkedForm::SuspendedParamLookup { name: Some(new_name.to_owned()), id: id.clone(), cdr_num: *cdr_num, car: *car, evaled: *evaled }), MarkedForm::SuspendedParamLookup { hash, name, id, cdr_num, car, evaled } => MarkedForm::new_suspended_param_lookup(Some(new_name.to_owned()), id.clone(), *cdr_num, *car, *evaled),
_ => Rc::clone(self), _ => Rc::clone(self),
} }
} }
@@ -404,8 +439,8 @@ impl MarkedForm {
pub fn decrement_wrap_level(&self) -> Option<Rc<Self>> { pub fn decrement_wrap_level(&self) -> Option<Rc<Self>> {
match self { match self {
MarkedForm::PrimComb { name, nonval_ok, takes_de, wrap_level, f } => Some(Rc::new(MarkedForm::PrimComb { name: name.clone(), nonval_ok: *nonval_ok, takes_de: *takes_de, wrap_level: wrap_level-1, f: *f })), MarkedForm::PrimComb { name, nonval_ok, takes_de, wrap_level, f } => Some(Rc::new(MarkedForm::PrimComb { name: name.clone(), nonval_ok: *nonval_ok, takes_de: *takes_de, wrap_level: wrap_level-1, f: *f })),
MarkedForm::DeriComb { lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body } => MarkedForm::DeriComb { hash, lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body } =>
Some(Rc::new(MarkedForm::DeriComb { lookup_name: lookup_name.clone(), ids: ids.clone(), se: Rc::clone(se), de: de.clone(), id: id.clone(), wrap_level: *wrap_level-1, sequence_params: sequence_params.clone(), rest_params: rest_params.clone(), body: Rc::clone(body) })), Some(MarkedForm::new_raw_deri_comb(lookup_name.clone(), ids.clone(), Rc::clone(se), de.clone(), id.clone(), *wrap_level-1, sequence_params.clone(), rest_params.clone(), Rc::clone(body))),
_ => None, _ => None,
} }
@@ -416,8 +451,8 @@ impl MarkedForm {
MarkedForm::Int(i) => NeededIds::new_none(), MarkedForm::Int(i) => NeededIds::new_none(),
MarkedForm::Bool(b) => NeededIds::new_none(), MarkedForm::Bool(b) => NeededIds::new_none(),
MarkedForm::Symbol(s) => NeededIds::new_none(), MarkedForm::Symbol(s) => NeededIds::new_none(),
MarkedForm::Pair(ids,car,cdr) => ids.clone(), MarkedForm::Pair( hash,ids,car,cdr) => ids.clone(),
MarkedForm::SuspendedSymbol(sus, name) => if let Some(sus) = sus { sus.ids() } else { NeededIds::new_true() }, MarkedForm::SuspendedSymbol( hash,sus, name) => if let Some(sus) = sus { sus.ids() } else { NeededIds::new_true() },
MarkedForm::SuspendedEnvLookup { id, .. } => NeededIds::new_single(id.clone()), MarkedForm::SuspendedEnvLookup { id, .. } => NeededIds::new_single(id.clone()),
MarkedForm::SuspendedParamLookup { id, .. } => NeededIds::new_single(id.clone()), MarkedForm::SuspendedParamLookup { id, .. } => NeededIds::new_single(id.clone()),
MarkedForm::SuspendedEnvEval { ids, ..} => ids.clone(), MarkedForm::SuspendedEnvEval { ids, ..} => ids.clone(),
@@ -434,21 +469,21 @@ impl MarkedForm {
MarkedForm::Int(i) => return true, MarkedForm::Int(i) => return true,
MarkedForm::Bool(b) => return true, MarkedForm::Bool(b) => return true,
MarkedForm::Symbol(s) => return true, MarkedForm::Symbol(s) => return true,
MarkedForm::SuspendedSymbol(sus, name) => return false, MarkedForm::SuspendedSymbol( hash,sus, name) => return false,
MarkedForm::SuspendedEnvLookup { id, .. } => return false, MarkedForm::SuspendedEnvLookup { id, .. } => return false,
MarkedForm::SuspendedParamLookup { id, .. } => return false, MarkedForm::SuspendedParamLookup { id, .. } => return false,
MarkedForm::SuspendedEnvEval { ids, ..} => return false, MarkedForm::SuspendedEnvEval { ids, ..} => return false,
MarkedForm::SuspendedIf { ids, ..} => return false, MarkedForm::SuspendedIf { ids, ..} => return false,
MarkedForm::SuspendedPair{ ids, .. } => return false, MarkedForm::SuspendedPair{ ids, .. } => return false,
MarkedForm::PrimComb { .. } => return true, MarkedForm::PrimComb { .. } => return true,
MarkedForm::Pair(ids,car,cdr) => ids.clone(), MarkedForm::Pair( hash,ids,car,cdr) => ids.clone(),
MarkedForm::DeriComb { ids, .. } => ids.clone(), MarkedForm::DeriComb { ids, .. } => ids.clone(),
}; };
ids.heads.is_empty() && ids.tails.is_empty() ids.heads.is_empty() && ids.tails.is_empty()
} }
pub fn is_pair(&self) -> bool { pub fn is_pair(&self) -> bool {
match self { match self {
MarkedForm::Pair(ids,car,cdr) => true, MarkedForm::Pair( hash,ids,car,cdr) => true,
_ => false, _ => false,
} }
} }
@@ -469,9 +504,9 @@ impl MarkedForm {
MarkedForm::Nil => Ok(Rc::clone(self)), MarkedForm::Nil => Ok(Rc::clone(self)),
MarkedForm::Int(i) => Ok(Rc::clone(self)), MarkedForm::Int(i) => Ok(Rc::clone(self)),
MarkedForm::Bool(b) => Ok(Rc::clone(self)), MarkedForm::Bool(b) => Ok(Rc::clone(self)),
MarkedForm::Symbol(s) => Ok(Rc::new(MarkedForm::SuspendedSymbol(None, s.clone()))), MarkedForm::Symbol(s) => Ok(MarkedForm::new_suspended_symbol(None, s.clone())),
MarkedForm::Pair(ids,car,cdr) => Ok(MarkedForm::new_suspended_pair(None, Some(NeededIds::new_true()), car.unval()?, Rc::clone(cdr), None)), MarkedForm::Pair( hash,ids,car,cdr) => Ok(MarkedForm::new_suspended_pair(None, Some(NeededIds::new_true()), car.unval()?, Rc::clone(cdr), None)),
MarkedForm::SuspendedSymbol(sus, name) => bail!("trying to unval a suspended symbol"), MarkedForm::SuspendedSymbol( hash,sus, name) => bail!("trying to unval a suspended symbol"),
MarkedForm::SuspendedEnvLookup { .. } => bail!("trying to unval a suspended env lookup"), MarkedForm::SuspendedEnvLookup { .. } => bail!("trying to unval a suspended env lookup"),
MarkedForm::SuspendedParamLookup { .. } => bail!("trying to unval a suspended param lookup"), MarkedForm::SuspendedParamLookup { .. } => bail!("trying to unval a suspended param lookup"),
MarkedForm::SuspendedEnvEval { .. } => bail!("trying to unval a suspended env eval"), MarkedForm::SuspendedEnvEval { .. } => bail!("trying to unval a suspended env eval"),
@@ -484,11 +519,11 @@ impl MarkedForm {
pub fn is_legal_env_chain(&self) -> Result<bool> { pub fn is_legal_env_chain(&self) -> Result<bool> {
let res = match self { let res = match self {
MarkedForm::Nil => Ok(true), MarkedForm::Nil => Ok(true),
MarkedForm::Pair(ids,car,cdr) => { MarkedForm::Pair( hash,ids,car,cdr) => {
match &**car { match &**car {
MarkedForm::Pair(idsp,carp,cdrp) => { MarkedForm::Pair( hash,idsp,carp,cdrp) => {
match &**cdrp { match &**cdrp {
MarkedForm::SuspendedSymbol(sus, name) => Ok(false), MarkedForm::SuspendedSymbol( hash,sus, name) => Ok(false),
MarkedForm::SuspendedEnvEval { .. } => Ok(false), MarkedForm::SuspendedEnvEval { .. } => Ok(false),
MarkedForm::SuspendedIf { .. } => Ok(false), MarkedForm::SuspendedIf { .. } => Ok(false),
MarkedForm::SuspendedPair{ ids, .. } => Ok(false), MarkedForm::SuspendedPair{ ids, .. } => Ok(false),
@@ -503,7 +538,7 @@ impl MarkedForm {
MarkedForm::SuspendedEnvLookup { .. } => Ok(true), MarkedForm::SuspendedEnvLookup { .. } => Ok(true),
MarkedForm::SuspendedParamLookup { .. } => Ok(false), MarkedForm::SuspendedParamLookup { .. } => Ok(false),
MarkedForm::SuspendedSymbol(sus, name) => Ok(false), MarkedForm::SuspendedSymbol( hash,sus, name) => Ok(false),
MarkedForm::SuspendedEnvEval { .. } => Ok(false), MarkedForm::SuspendedEnvEval { .. } => Ok(false),
MarkedForm::SuspendedIf { .. } => Ok(false), MarkedForm::SuspendedIf { .. } => Ok(false),
MarkedForm::SuspendedPair{ ids, .. } => Ok(false), MarkedForm::SuspendedPair{ ids, .. } => Ok(false),
@@ -514,7 +549,7 @@ impl MarkedForm {
MarkedForm::PrimComb { .. } => bail!("bad env {}", self), MarkedForm::PrimComb { .. } => bail!("bad env {}", self),
MarkedForm::DeriComb { .. } => bail!("bad env {}", self), MarkedForm::DeriComb { .. } => bail!("bad env {}", self),
}; };
println!("I was legal {:?} - {}", res, self); //println!("I was legal {:?} - {}", res, self);
res res
} }
pub fn truthy(&self) -> Result<bool> { pub fn truthy(&self) -> Result<bool> {
@@ -523,8 +558,8 @@ impl MarkedForm {
MarkedForm::Int(i) => Ok(true), MarkedForm::Int(i) => Ok(true),
MarkedForm::Bool(b) => Ok(*b), MarkedForm::Bool(b) => Ok(*b),
MarkedForm::Symbol(s) => Ok(true), MarkedForm::Symbol(s) => Ok(true),
MarkedForm::Pair(ids,car,cdr) => Ok(true), MarkedForm::Pair( hash,ids,car,cdr) => Ok(true),
MarkedForm::SuspendedSymbol(sus, name) => bail!("trying to truthy a suspended symbol"), MarkedForm::SuspendedSymbol( hash,sus, name) => bail!("trying to truthy a suspended symbol"),
MarkedForm::SuspendedEnvLookup { .. } => bail!("trying to truthy a suspended env lookup"), MarkedForm::SuspendedEnvLookup { .. } => bail!("trying to truthy a suspended env lookup"),
MarkedForm::SuspendedParamLookup { .. } => bail!("trying to truthy a suspended param lookup"), MarkedForm::SuspendedParamLookup { .. } => bail!("trying to truthy a suspended param lookup"),
MarkedForm::SuspendedEnvEval { .. } => bail!("trying to truthy a suspended env eval"), MarkedForm::SuspendedEnvEval { .. } => bail!("trying to truthy a suspended env eval"),
@@ -554,17 +589,17 @@ impl MarkedForm {
} }
pub fn car(&self) -> Result<Rc<MarkedForm>> { pub fn car(&self) -> Result<Rc<MarkedForm>> {
match self { match self {
MarkedForm::Pair(ids,car,cdr) => Ok(Rc::clone(car)), MarkedForm::Pair(h,ids,car,cdr) => Ok(Rc::clone(car)),
MarkedForm::SuspendedParamLookup { name, id, cdr_num, car, evaled } if !car && !evaled => Ok(Rc::new(MarkedForm::SuspendedParamLookup { name: name.clone(), id: id.clone(), MarkedForm::SuspendedParamLookup { hash, name, id, cdr_num, car, evaled } if !car && !evaled => Ok(MarkedForm::new_suspended_param_lookup(name.clone(), id.clone(),
cdr_num: *cdr_num, car: true, evaled: false })), *cdr_num, true, false)),
_ => bail!("not a pair for car: {}", self), _ => bail!("not a pair for car: {}", self),
} }
} }
pub fn cdr(&self) -> Result<Rc<MarkedForm>> { pub fn cdr(&self) -> Result<Rc<MarkedForm>> {
match self { match self {
MarkedForm::Pair(ids,car,cdr) => Ok(Rc::clone(cdr)), MarkedForm::Pair(h,ids,car,cdr) => Ok(Rc::clone(cdr)),
MarkedForm::SuspendedParamLookup { name, id, cdr_num, car, evaled } if !car && !evaled => Ok(Rc::new(MarkedForm::SuspendedParamLookup { name: name.clone(), id: id.clone(), MarkedForm::SuspendedParamLookup { hash, name, id, cdr_num, car, evaled } if !car && !evaled => Ok(MarkedForm::new_suspended_param_lookup(name.clone(), id.clone(),
cdr_num: *cdr_num+1, car: *car, evaled: false })), *cdr_num+1, *car, false)),
_ => bail!("not a pair for cdr: {}", self), _ => bail!("not a pair for cdr: {}", self),
} }
} }
@@ -577,10 +612,10 @@ fn eval_func(bctx: BCtx, dctx: DCtx, p: Rc<MarkedForm>) -> Result<(BCtx,Rc<Marke
let x = p.car()?; let x = p.car()?;
let e = p.cdr()?.car()?; let e = p.cdr()?.car()?;
if !x.is_value() { if !x.is_value() {
println!("Checking compatability"); //println!("Checking compatability");
if let (MarkedForm::SuspendedParamLookup { name, id, cdr_num, car, evaled: false }, MarkedForm::SuspendedEnvLookup { name: oname, id: oid }) = (&*x, &*e) { if let (MarkedForm::SuspendedParamLookup { name, id, cdr_num, car, evaled: false, .. }, MarkedForm::SuspendedEnvLookup { name: oname, id: oid, .. }) = (&*x, &*e) {
if id == oid { if id == oid {
return Ok((bctx, Rc::new(MarkedForm::SuspendedParamLookup { name: name.clone(), id: id.clone(), cdr_num: *cdr_num, car: *car, evaled: true }))); return Ok((bctx, MarkedForm::new_suspended_param_lookup(name.clone(), id.clone(), *cdr_num, *car, true)));
} }
} }
Ok((bctx, MarkedForm::new_suspended_pair( None, Some(x.ids()), make_eval_prim(0), p, None ))) Ok((bctx, MarkedForm::new_suspended_pair( None, Some(x.ids()), make_eval_prim(0), p, None )))
@@ -670,7 +705,7 @@ pub fn mark(form: Rc<Form>, bctx: BCtx) -> (BCtx, Rc<MarkedForm>) {
let wrap_level = 0; let wrap_level = 0;
let sequence_params = vec![]; let sequence_params = vec![];
let rest_params = Some(params); let rest_params = Some(params);
println!("vau, making a new func {:?} - {}", id, p); //println!("vau, making a new func {:?} - {}", id, p);
Ok((bctx, MarkedForm::new_deri_comb( se, None, de, id, wrap_level, sequence_params, rest_params, body, None ))) Ok((bctx, MarkedForm::new_deri_comb( se, None, de, id, wrap_level, sequence_params, rest_params, body, None )))
}}), }}),
"eval" => make_eval_prim(1), "eval" => make_eval_prim(1),
@@ -692,7 +727,7 @@ pub fn mark(form: Rc<Form>, bctx: BCtx) -> (BCtx, Rc<MarkedForm>) {
let t = p.cdr()?.car()?.unval()?; let t = p.cdr()?.car()?.unval()?;
let e = p.cdr()?.cdr()?.car()?.unval()?; let e = p.cdr()?.cdr()?.car()?.unval()?;
let ids = c.ids().union(&t.ids()).union(&e.ids()); let ids = c.ids().union(&t.ids()).union(&e.ids());
Ok((bctx, Rc::new(MarkedForm::SuspendedIf{ids, env: None, c, t, e}))) Ok((bctx, MarkedForm::new_suspended_if(ids, None, c, t, e)))
}}), }}),
// Non val is actually fine // Non val is actually fine
"quote" => Rc::new(MarkedForm::PrimComb { name: "quote".to_owned(), nonval_ok: true, takes_de: false, wrap_level: 0, f: |bctx, dctx, p| { "quote" => Rc::new(MarkedForm::PrimComb { name: "quote".to_owned(), nonval_ok: true, takes_de: false, wrap_level: 0, f: |bctx, dctx, p| {
@@ -774,7 +809,7 @@ pub fn mark(form: Rc<Form>, bctx: BCtx) -> (BCtx, Rc<MarkedForm>) {
// This could allow nonval with fallback // This could allow nonval with fallback
"pair?" => Rc::new(MarkedForm::PrimComb { name: "pair?".to_owned(), nonval_ok: false, takes_de: false, wrap_level: 1, f: |bctx, dctx, p| { "pair?" => Rc::new(MarkedForm::PrimComb { name: "pair?".to_owned(), nonval_ok: false, takes_de: false, wrap_level: 1, f: |bctx, dctx, p| {
Ok((bctx, Rc::new(MarkedForm::Bool(match &* p.car()? { Ok((bctx, Rc::new(MarkedForm::Bool(match &* p.car()? {
MarkedForm::Pair(_i, _a,_b) => true, MarkedForm::Pair(_h, _i, _a,_b) => true,
_ => false, _ => false,
})))) }))))
}}), }}),
@@ -819,17 +854,17 @@ pub fn partial_eval(bctx_in: BCtx, dctx: DCtx, form: Rc<MarkedForm>) -> Result<(
let mut next_form = Some(Rc::clone(&form)); let mut next_form = Some(Rc::clone(&form));
loop { loop {
let x = next_form.take().unwrap(); let x = next_form.take().unwrap();
println!("{:ident$}PE: {}", "", x, ident=dctx.ident*4); //println!("{:ident$}PE: {}", "", x, ident=dctx.ident*4);
if !dctx.can_progress(x.ids()) { if !dctx.can_progress(x.ids()) {
println!("{:ident$}Shouldn't go! (because of {:?} with {:?}/{:?})", "", x.ids(), dctx.real_set, dctx.fake_set, ident=dctx.ident*4); //println!("{:ident$}Shouldn't go! (because of {:?} with {:?}/{:?})", "", x.ids(), dctx.real_set, dctx.fake_set, ident=dctx.ident*4);
assert!(x.is_value() || !dctx.fake_set.is_empty()); assert!(x.is_value() || !dctx.fake_set.is_empty());
if form.is_legal_env_chain().unwrap_or(false) && x != form { if form.is_legal_env_chain().unwrap_or(false) && x != form {
//if x != form { //if x != form {
let form_ids = form.ids(); let form_ids = form.ids();
assert!(!form_ids.may_contain_id(&true_id)); assert!(!form_ids.may_contain_id(&true_id));
if !x.is_legal_env_chain().unwrap_or(false) { //if !x.is_legal_env_chain().unwrap_or(false) {
println!("Went from legal hash chain {} to {}", form, x); //println!("Went from legal hash chain {} to {}", form, x);
} //}
assert!(x.is_legal_env_chain().unwrap_or(false)); assert!(x.is_legal_env_chain().unwrap_or(false));
bctx.memo.insert(form, (dctx.real_hash_set(), None, Rc::clone(&x))); bctx.memo.insert(form, (dctx.real_hash_set(), None, Rc::clone(&x)));
//bctx.memo.insert(form, (dctx.real_hash_set(), if form_ids.may_contain_id(&true_id) { Some(calculate_hash(&dctx.e)) } else { None }, Rc::clone(&x))); //bctx.memo.insert(form, (dctx.real_hash_set(), if form_ids.may_contain_id(&true_id) { Some(calculate_hash(&dctx.e)) } else { None }, Rc::clone(&x)));
@@ -842,10 +877,10 @@ pub fn partial_eval(bctx_in: BCtx, dctx: DCtx, form: Rc<MarkedForm>) -> Result<(
//if false { //if false {
if got.map(|(ids,maybe_e_hash,it)| maybe_e_hash.map(|h| h == calculate_hash(&dctx.e)).unwrap_or(true) && dctx.real_hash_set().is_superset(ids)).unwrap_or(false) { if got.map(|(ids,maybe_e_hash,it)| maybe_e_hash.map(|h| h == calculate_hash(&dctx.e)).unwrap_or(true) && dctx.real_hash_set().is_superset(ids)).unwrap_or(false) {
let skip = Rc::clone(&got.unwrap().2); let skip = Rc::clone(&got.unwrap().2);
println!("{:ident$}({}) PE {} skip forwards to {}", "", dctx.ident, x, skip, ident=dctx.ident*4); //println!("{:ident$}({}) PE {} skip forwards to {}", "", dctx.ident, x, skip, ident=dctx.ident*4);
next_form = Some(skip); next_form = Some(skip);
} else { } else {
println!("{:ident$}({}) PE {} (because of {:?} with {:?}/{:?})", "", dctx.ident, x, x.ids(), dctx.real_set, dctx.fake_set, ident=dctx.ident*4); //println!("{:ident$}({}) PE {} (because of {:?} with {:?}/{:?})", "", dctx.ident, x, x.ids(), dctx.real_set, dctx.fake_set, ident=dctx.ident*4);
let (new_bctx, new_form) = partial_eval_step(&x, bctx.clone(), &dctx)?; let (new_bctx, new_form) = partial_eval_step(&x, bctx.clone(), &dctx)?;
bctx = new_bctx; bctx = new_bctx;
// basic Drop redundent veval // basic Drop redundent veval
@@ -859,7 +894,7 @@ pub fn partial_eval(bctx_in: BCtx, dctx: DCtx, form: Rc<MarkedForm>) -> Result<(
// SUSPENDED CALLS THAT TAKE IN THE DE // SUSPENDED CALLS THAT TAKE IN THE DE
if let MarkedForm::SuspendedEnvEval { x, e, .. } = &*new_form { if let MarkedForm::SuspendedEnvEval { x, e, .. } = &*new_form {
if !x.ids().may_contain_id(&true_id) && e.is_legal_env_chain()? { if !x.ids().may_contain_id(&true_id) && e.is_legal_env_chain()? {
println!("{:ident$}Dropping redundent eval: {} from {}", "", x, e, ident=dctx.ident*4); //println!("{:ident$}Dropping redundent eval: {} from {}", "", x, e, ident=dctx.ident*4);
//println!("{:ident$}Dropping redundent eval: {}", "", x, ident=dctx.ident*4); //println!("{:ident$}Dropping redundent eval: {}", "", x, ident=dctx.ident*4);
next_form = Some(Rc::clone(x)); next_form = Some(Rc::clone(x));
// do we still need force for drop redundent veval? // do we still need force for drop redundent veval?
@@ -881,7 +916,7 @@ enum MapUnvalPEvalResult {
fn map_unval_peval(bctx: BCtx, dctx: DCtx, x: Rc<MarkedForm>) -> MapUnvalPEvalResult { fn map_unval_peval(bctx: BCtx, dctx: DCtx, x: Rc<MarkedForm>) -> MapUnvalPEvalResult {
match &*x { match &*x {
MarkedForm::Nil => MapUnvalPEvalResult::Ok(bctx,x), MarkedForm::Nil => MapUnvalPEvalResult::Ok(bctx,x),
MarkedForm::Pair(ids, x_car, x_cdr) => { MarkedForm::Pair(_h, ids, x_car, x_cdr) => {
match x_car.unval() { match x_car.unval() {
Ok(unval) => { Ok(unval) => {
match partial_eval(bctx, dctx.clone(), unval) { match partial_eval(bctx, dctx.clone(), unval) {
@@ -902,10 +937,10 @@ fn map_unval_peval(bctx: BCtx, dctx: DCtx, x: Rc<MarkedForm>) -> MapUnvalPEvalRe
MarkedForm::Bool(b) => MapUnvalPEvalResult::BadError(anyhow!("map_unval_peval over not a list")), MarkedForm::Bool(b) => MapUnvalPEvalResult::BadError(anyhow!("map_unval_peval over not a list")),
MarkedForm::Symbol(s) => MapUnvalPEvalResult::BadError(anyhow!("map_unval_peval over not a list")), MarkedForm::Symbol(s) => MapUnvalPEvalResult::BadError(anyhow!("map_unval_peval over not a list")),
MarkedForm::PrimComb { .. } => MapUnvalPEvalResult::BadError(anyhow!("map_unval_peval over not a list")), MarkedForm::PrimComb { .. } => MapUnvalPEvalResult::BadError(anyhow!("map_unval_peval over not a list")),
MarkedForm::Pair(ids,car,cdr) => MapUnvalPEvalResult::BadError(anyhow!("map_unval_peval over not a list")), MarkedForm::Pair(h,ids,car,cdr) => MapUnvalPEvalResult::BadError(anyhow!("map_unval_peval over not a list")),
MarkedForm::DeriComb { ids, .. } => MapUnvalPEvalResult::BadError(anyhow!("map_unval_peval over not a list")), MarkedForm::DeriComb { ids, .. } => MapUnvalPEvalResult::BadError(anyhow!("map_unval_peval over not a list")),
MarkedForm::SuspendedSymbol(sus, name) => MapUnvalPEvalResult::NotYet(anyhow!("map_unval_peval over not (yet) a list")), MarkedForm::SuspendedSymbol(h, sus, name) => MapUnvalPEvalResult::NotYet(anyhow!("map_unval_peval over not (yet) a list")),
MarkedForm::SuspendedEnvLookup { id, .. } => MapUnvalPEvalResult::NotYet(anyhow!("map_unval_peval over not (yet) a list")), MarkedForm::SuspendedEnvLookup { id, .. } => MapUnvalPEvalResult::NotYet(anyhow!("map_unval_peval over not (yet) a list")),
MarkedForm::SuspendedParamLookup { id, .. } => MapUnvalPEvalResult::NotYet(anyhow!("map_unval_peval over not (yet) a list")), MarkedForm::SuspendedParamLookup { id, .. } => MapUnvalPEvalResult::NotYet(anyhow!("map_unval_peval over not (yet) a list")),
MarkedForm::SuspendedEnvEval { ids, ..} => MapUnvalPEvalResult::NotYet(anyhow!("map_unval_peval over not (yet) a list")), MarkedForm::SuspendedEnvEval { ids, ..} => MapUnvalPEvalResult::NotYet(anyhow!("map_unval_peval over not (yet) a list")),
@@ -917,16 +952,16 @@ fn map_unval_peval(bctx: BCtx, dctx: DCtx, x: Rc<MarkedForm>) -> MapUnvalPEvalRe
fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &DCtx) -> Result<(BCtx,Rc<MarkedForm>)> { fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &DCtx) -> Result<(BCtx,Rc<MarkedForm>)> {
//println!("{:ident$}({}) {}", "", dctx.ident, x, ident=dctx.ident*4); //println!("{:ident$}({}) {}", "", dctx.ident, x, ident=dctx.ident*4);
match &**x { match &**x {
MarkedForm::Pair(ids,car,cdr) => { MarkedForm::Pair(h,ids,car,cdr) => {
//println!("{:ident$}pair ({}) {}", "", dctx.ident, x, ident=dctx.ident*4); //println!("{:ident$}pair ({}) {}", "", dctx.ident, x, ident=dctx.ident*4);
let (bctx, car) = partial_eval(bctx, dctx.clone(), Rc::clone(car))?; let (bctx, car) = partial_eval(bctx, dctx.clone(), Rc::clone(car))?;
let (bctx, cdr) = partial_eval(bctx, dctx.clone(), Rc::clone(cdr))?; let (bctx, cdr) = partial_eval(bctx, dctx.clone(), Rc::clone(cdr))?;
Ok((bctx, MarkedForm::new_pair(car, cdr))) Ok((bctx, MarkedForm::new_pair(car, cdr)))
}, },
MarkedForm::SuspendedSymbol(sus, name) => { MarkedForm::SuspendedSymbol(h, sus, name) => {
// Have to account for the *weird* case that the env chain ends in a suspended param / suspended env // Have to account for the *weird* case that the env chain ends in a suspended param / suspended env
//println!("Lookin up symbol {}", name); //println!("Lookin up symbol {}", name);
println!("Lookin up symbol {} in {}", name, dctx.e); //println!("Lookin up symbol {} in {}", name, dctx.e);
let (bctx, mut t) = if let Some(sus) = sus { let (bctx, mut t) = if let Some(sus) = sus {
partial_eval(bctx, dctx.clone(), Rc::clone(sus))? partial_eval(bctx, dctx.clone(), Rc::clone(sus))?
} else { } else {
@@ -935,7 +970,7 @@ fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &DCtx) -> Result<(BCt
loop { loop {
if let Ok(cmp) = t.car().and_then(|kv| kv.car()).and_then(|s| s.sym().map(|s| s.to_owned())) { if let Ok(cmp) = t.car().and_then(|kv| kv.car()).and_then(|s| s.sym().map(|s| s.to_owned())) {
if *name == cmp { if *name == cmp {
println!("\tgot for symbol {} {}", name, t.car()?.cdr()?.tag_name(name)); //println!("\tgot for symbol {} {}", name, t.car()?.cdr()?.tag_name(name));
return Ok((bctx, t.car()?.cdr()?.tag_name(name))); return Ok((bctx, t.car()?.cdr()?.tag_name(name)));
} else { } else {
t = t.cdr()?; t = t.cdr()?;
@@ -944,28 +979,28 @@ fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &DCtx) -> Result<(BCt
// bad env // bad env
match &*t { match &*t {
MarkedForm::Nil => bail!("Lookup for {} not found!", name), MarkedForm::Nil => bail!("Lookup for {} not found!", name),
MarkedForm::SuspendedSymbol(sus, name) => break, MarkedForm::SuspendedSymbol(h,sus, name) => break,
MarkedForm::SuspendedEnvLookup { .. } => break, MarkedForm::SuspendedEnvLookup { .. } => break,
MarkedForm::SuspendedParamLookup { .. } => break, MarkedForm::SuspendedParamLookup { .. } => break,
MarkedForm::SuspendedEnvEval { .. } => break, MarkedForm::SuspendedEnvEval { .. } => break,
MarkedForm::SuspendedIf { .. } => break, MarkedForm::SuspendedIf { .. } => break,
MarkedForm::SuspendedPair { .. } => break, MarkedForm::SuspendedPair { .. } => break,
MarkedForm::Pair(ids,car,cdr) => break, MarkedForm::Pair(h,ids,car,cdr) => break,
_ => bail!("Illegal lookup for {}", name), _ => bail!("Illegal lookup for {}", name),
} }
} }
} }
println!("\tcouldn't find it, returning suspended"); //println!("\tcouldn't find it, returning suspended");
return Ok((bctx, Rc::new(MarkedForm::SuspendedSymbol(Some(t), name.clone())))); return Ok((bctx, MarkedForm::new_suspended_symbol(Some(t), name.clone())));
}, },
MarkedForm::SuspendedEnvLookup { name, id } => { MarkedForm::SuspendedEnvLookup { hash, name, id } => {
if let Some(v) = dctx.sus_env_stack.get(id) { if let Some(v) = dctx.sus_env_stack.get(id) {
Ok((bctx, if let Some(name) = name { v.tag_name(name) } else { Rc::clone(v) })) Ok((bctx, if let Some(name) = name { v.tag_name(name) } else { Rc::clone(v) }))
} else { } else {
panic!("failed env lookup (forced)"); panic!("failed env lookup (forced)");
} }
}, },
MarkedForm::SuspendedParamLookup { name, id, cdr_num, car, evaled } => { MarkedForm::SuspendedParamLookup { hash, name, id, cdr_num, car, evaled } => {
if let Some(v) = dctx.sus_prm_stack.get(id) { if let Some(v) = dctx.sus_prm_stack.get(id) {
let mut translated_value = if let Some(name) = name { v.tag_name(name) } else { Rc::clone(v) }; let mut translated_value = if let Some(name) = name { v.tag_name(name) } else { Rc::clone(v) };
for i in 0..*cdr_num { for i in 0..*cdr_num {
@@ -977,7 +1012,7 @@ fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &DCtx) -> Result<(BCt
if *evaled { if *evaled {
// but with this, we have to deal with unval failures // but with this, we have to deal with unval failures
// actually, do we have to deal with unval failures? // actually, do we have to deal with unval failures?
translated_value = MarkedForm::new_suspended_env_eval(translated_value.unval().unwrap(), Rc::new(MarkedForm::SuspendedEnvLookup { name: None, id: id.clone() })); translated_value = MarkedForm::new_suspended_env_eval(translated_value.unval().unwrap(), MarkedForm::new_suspended_env_lookup(None, id.clone()));
} }
Ok((bctx, translated_value)) Ok((bctx, translated_value))
} else { } else {
@@ -1040,10 +1075,10 @@ fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &DCtx) -> Result<(BCt
c_ids.union(&t_ids).union(&e_ids) c_ids.union(&t_ids).union(&e_ids)
}; };
Ok((bctx, Rc::new(MarkedForm::SuspendedIf {ids, env, c, t, e }))) Ok((bctx, MarkedForm::new_suspended_if(ids, env, c, t, e)))
} }
}, },
MarkedForm::DeriComb { lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body } => { MarkedForm::DeriComb { hash, lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body } => {
// TODO: figure out wrap level, sequence params, etc // TODO: figure out wrap level, sequence params, etc
// the current env is our new se // the current env is our new se
let se = Rc::clone(&dctx.e); let se = Rc::clone(&dctx.e);
@@ -1051,23 +1086,23 @@ fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &DCtx) -> Result<(BCt
match dctx.copy_push_frame(id.clone(), &se, &de, None, &rest_params, None, body) { match dctx.copy_push_frame(id.clone(), &se, &de, None, &rest_params, None, body) {
PushFrameResult::Ok(inner_dctx) => { PushFrameResult::Ok(inner_dctx) => {
println!("{:ident$}Doing a body deri for {:?} which is {}", "", lookup_name, x, ident=ident_amount); //println!("{:ident$}Doing a body deri for {:?} which is {}", "", lookup_name, x, ident=ident_amount);
println!("{:ident$}and also body ids is {:?}", "", body.ids(), ident=ident_amount); //println!("{:ident$}and also body ids is {:?}", "", body.ids(), ident=ident_amount);
let (bctx, body) = partial_eval(bctx, inner_dctx, Rc::clone(&body))?; let (bctx, body) = partial_eval(bctx, inner_dctx, Rc::clone(&body))?;
//println!("{:ident$}result was {}", "", body, ident=ident_amount); //println!("{:ident$}result was {}", "", body, ident=ident_amount);
Ok((bctx, MarkedForm::new_deri_comb(se, lookup_name.clone(), de.clone(), id.clone(), *wrap_level, sequence_params.clone(), rest_params.clone(), body, None))) Ok((bctx, MarkedForm::new_deri_comb(se, lookup_name.clone(), de.clone(), id.clone(), *wrap_level, sequence_params.clone(), rest_params.clone(), body, None)))
}, },
PushFrameResult::UnderBody(rec_stop_under) => { PushFrameResult::UnderBody(rec_stop_under) => {
println!("{:ident$}call of {:?} failed b/c rec_stop_under b/c BODY", "", lookup_name, ident=dctx.ident*4); //println!("{:ident$}call of {:?} failed b/c rec_stop_under b/c BODY", "", lookup_name, ident=dctx.ident*4);
Ok((bctx, MarkedForm::new_deri_comb(se, lookup_name.clone(), de.clone(), id.clone(), *wrap_level, sequence_params.clone(), rest_params.clone(), Rc::clone(body), Some(rec_stop_under)))) Ok((bctx, MarkedForm::new_deri_comb(se, lookup_name.clone(), de.clone(), id.clone(), *wrap_level, sequence_params.clone(), rest_params.clone(), Rc::clone(body), Some(rec_stop_under))))
}, },
PushFrameResult::UnderIf(rec_stop_under) => { PushFrameResult::UnderIf(rec_stop_under) => {
println!("{:ident$}call of {:?} failed b/c rec_stop_under b/c IF", "", lookup_name, ident=dctx.ident*4); //println!("{:ident$}call of {:?} failed b/c rec_stop_under b/c IF", "", lookup_name, ident=dctx.ident*4);
Ok((bctx, MarkedForm::new_deri_comb(se, lookup_name.clone(), de.clone(), id.clone(), *wrap_level, sequence_params.clone(), rest_params.clone(), Rc::clone(body), Some(rec_stop_under)))) Ok((bctx, MarkedForm::new_deri_comb(se, lookup_name.clone(), de.clone(), id.clone(), *wrap_level, sequence_params.clone(), rest_params.clone(), Rc::clone(body), Some(rec_stop_under))))
}, },
} }
}, },
MarkedForm::SuspendedPair { ids, env, car, cdr } => { MarkedForm::SuspendedPair { hash, ids, env, car, cdr } => {
let ( bctx, env) = if let Some(env) = env { let ( bctx, env) = if let Some(env) = env {
partial_eval(bctx, dctx.clone(), Rc::clone(env))? partial_eval(bctx, dctx.clone(), Rc::clone(env))?
} else { } else {
@@ -1087,11 +1122,11 @@ fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &DCtx) -> Result<(BCt
bctx = new_bctx; bctx = new_bctx;
}, },
MapUnvalPEvalResult::NotYet(e) => { MapUnvalPEvalResult::NotYet(e) => {
println!("{:ident$} evaling parameters failed (for now) b/c {:?}", "", e, ident=dctx.ident*4); //println!("{:ident$} evaling parameters failed (for now) b/c {:?}", "", e, ident=dctx.ident*4);
break; break;
}, },
MapUnvalPEvalResult::BadError(e) => { MapUnvalPEvalResult::BadError(e) => {
println!("{:ident$} evaling parameters failed (FOREVER) b/c {:?}", "", e, ident=dctx.ident*4); //println!("{:ident$} evaling parameters failed (FOREVER) b/c {:?}", "", e, ident=dctx.ident*4);
return Err(e); return Err(e);
}, },
} }
@@ -1104,15 +1139,15 @@ fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &DCtx) -> Result<(BCt
if !nonval_ok && !cdr.is_value() { if !nonval_ok && !cdr.is_value() {
break; break;
} }
println!("{:ident$}doing a call eval of {}", "", name, ident=dctx.ident*4); //println!("{:ident$}doing a call eval of {}", "", name, ident=dctx.ident*4);
//println!("{:ident$}parameters {} are? a val because {:?}", "", cdr, cdr.ids(), ident=dctx.ident*4); //println!("{:ident$}parameters {} are? a val because {:?}", "", cdr, cdr.ids(), ident=dctx.ident*4);
//return f(bctx.clone(), dctx.clone(), Rc::clone(&cdr)); //return f(bctx.clone(), dctx.clone(), Rc::clone(&cdr));
let (bctx,result) = f(bctx.clone(), dctx.copy_set_env(&env), Rc::clone(&cdr))?; let (bctx,result) = f(bctx.clone(), dctx.copy_set_env(&env), Rc::clone(&cdr))?;
//println!("{:ident$}successful result is {}", "", result, ident=dctx.ident*4); //println!("{:ident$}successful result is {}", "", result, ident=dctx.ident*4);
println!("{:ident$}successful result", "", ident=dctx.ident*4); //println!("{:ident$}successful result", "", ident=dctx.ident*4);
return Ok((bctx,result)); return Ok((bctx,result));
} }
MarkedForm::DeriComb { lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body } => { MarkedForm::DeriComb { hash, lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body } => {
need_denv = de.is_some(); need_denv = de.is_some();
let saved_env = if need_denv { Some(Rc::clone(&env)) } else { None }; let saved_env = if need_denv { Some(Rc::clone(&env)) } else { None };
if !cdr.is_value() { if !cdr.is_value() {
@@ -1133,7 +1168,7 @@ fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &DCtx) -> Result<(BCt
PushFrameResult::Ok(inner_dctx) => { PushFrameResult::Ok(inner_dctx) => {
let ident_amount = inner_dctx.ident*4; let ident_amount = inner_dctx.ident*4;
//println!("{:ident$}doing a call eval of {} in {}", "", body, inner_dctx.e, ident=inner_dctx.ident*4); //println!("{:ident$}doing a call eval of {} in {}", "", body, inner_dctx.e, ident=inner_dctx.ident*4);
println!("{:ident$}doing a call eval of {:?}", "", lookup_name, ident=ident_amount); //println!("{:ident$}doing a call eval of {:?}", "", lookup_name, ident=ident_amount);
//println!("{:ident$}with_parameters {}", "", cdr, ident=ident_amount); //println!("{:ident$}with_parameters {}", "", cdr, ident=ident_amount);
//Here is where we could do a tail call instead, but there //Here is where we could do a tail call instead, but there
@@ -1145,25 +1180,21 @@ fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &DCtx) -> Result<(BCt
return Ok((bctx, MarkedForm::new_suspended_pair( saved_env, Some(r.ids()), car, cdr, None))); return Ok((bctx, MarkedForm::new_suspended_pair( saved_env, Some(r.ids()), car, cdr, None)));
} }
}, },
PushFrameResult::UnderBody(rec_stop_under) => { PushFrameResult::UnderBody(rec_stop_under) => { unreachable!() },
unreachable!()
//println!("{:ident$}call of {:?} failed b/c rec_stop_under of body", "", lookup_name, ident=dctx.ident*4);
//return Ok((bctx, MarkedForm::new_suspended_pair( saved_env, None, car, cdr, Some(rec_stop_under), None)));
},
PushFrameResult::UnderIf(rec_stop_under) => { PushFrameResult::UnderIf(rec_stop_under) => {
println!("{:ident$}call of {:?} failed b/c rec_stop_under of if", "", lookup_name, ident=dctx.ident*4); //println!("{:ident$}call of {:?} failed b/c rec_stop_under of if", "", lookup_name, ident=dctx.ident*4);
return Ok((bctx, MarkedForm::new_suspended_pair( saved_env, None, car, cdr, Some(rec_stop_under)))); return Ok((bctx, MarkedForm::new_suspended_pair( saved_env, None, car, cdr, Some(rec_stop_under))));
}, },
} }
}, },
// These are illegal values // These are illegal values
MarkedForm::Nil => bail!("tried to call a bad value {:?}", car), MarkedForm::Nil => bail!("tried to call a bad value {:?}", car),
MarkedForm::Pair(ids, x_car, x_cdr) => bail!("tried to call a bad value {:?}", car), MarkedForm::Pair(h, ids, x_car, x_cdr) => bail!("tried to call a bad value {:?}", car),
MarkedForm::Int(i) => bail!("tried to call a bad value {:?}", car), MarkedForm::Int(i) => bail!("tried to call a bad value {:?}", car),
MarkedForm::Bool(b) => bail!("tried to call a bad value {:?}", car), MarkedForm::Bool(b) => bail!("tried to call a bad value {:?}", car),
MarkedForm::Symbol(s) => bail!("tried to call a bad value {:?}", car), MarkedForm::Symbol(s) => bail!("tried to call a bad value {:?}", car),
MarkedForm::PrimComb { .. } => bail!("tried to call a bad value {:?}", car), MarkedForm::PrimComb { .. } => bail!("tried to call a bad value {:?}", car),
MarkedForm::Pair(ids,car,cdr) => bail!("tried to call a bad value {:?}", car), MarkedForm::Pair(h,ids,car,cdr) => bail!("tried to call a bad value {:?}", car),
MarkedForm::DeriComb { ids, .. } => bail!("tried to call a bad value {:?}", car), MarkedForm::DeriComb { ids, .. } => bail!("tried to call a bad value {:?}", car),
_ => {}, // suspended, so reform _ => {}, // suspended, so reform
} }
@@ -1185,13 +1216,13 @@ impl fmt::Display for MarkedForm {
MarkedForm::Int(i) => write!(f, "{}", i), MarkedForm::Int(i) => write!(f, "{}", i),
MarkedForm::Bool(b) => write!(f, "{}", b), MarkedForm::Bool(b) => write!(f, "{}", b),
MarkedForm::Symbol(s) => write!(f, "{}", s), MarkedForm::Symbol(s) => write!(f, "{}", s),
MarkedForm::Pair( ids, car, cdr) => { MarkedForm::Pair( h, ids, car, cdr) => {
//write!(f, "{:?}#({}", ids, car)?; //write!(f, "{:?}#({}", ids, car)?;
write!(f, "({}", car)?; write!(f, "({}", car)?;
let mut traverse: Rc<MarkedForm> = Rc::clone(cdr); let mut traverse: Rc<MarkedForm> = Rc::clone(cdr);
loop { loop {
match &*traverse { match &*traverse {
MarkedForm::Pair( ref ids, ref carp, ref cdrp) => { MarkedForm::Pair( ref h, ref ids, ref carp, ref cdrp) => {
write!(f, " {}", carp)?; write!(f, " {}", carp)?;
traverse = Rc::clone(cdrp); traverse = Rc::clone(cdrp);
}, },
@@ -1206,26 +1237,25 @@ impl fmt::Display for MarkedForm {
} }
} }
}, },
MarkedForm::SuspendedEnvEval { ids, x, e } => write!(f, "({}){{Sveval {} {}}}", ids, x, e), MarkedForm::SuspendedEnvEval { hash, ids, x, e } => write!(f, "({}){{Sveval {} {}}}", ids, x, e),
MarkedForm::SuspendedIf { ids, env, c, t, e } => { MarkedForm::SuspendedIf { hash, ids, env, c, t, e } => {
if env.is_some() { if env.is_some() {
write!(f, "({})#HasEnv{{Sif {} {} {}}}", ids, c, t, e) write!(f, "({})#HasEnv{{Sif {} {} {}}}", ids, c, t, e)
} else { } else {
write!(f, "({}){{Sif {} {} {}}}", ids, c, t, e) write!(f, "({}){{Sif {} {} {}}}", ids, c, t, e)
} }
}, },
MarkedForm::SuspendedSymbol(sus,name) => if let Some(sus) = sus { write!(f, "({}){}", sus, name) } else { write!(f, "(){}", name) }, MarkedForm::SuspendedSymbol( hash,sus,name) => if let Some(sus) = sus { write!(f, "({}){}", sus, name) } else { write!(f, "(){}", name) },
MarkedForm::SuspendedEnvLookup { name, id } => write!(f, "{:?}({:?}env)", name, id), MarkedForm::SuspendedEnvLookup { hash, name, id } => write!(f, "{:?}({:?}env)", name, id),
MarkedForm::SuspendedParamLookup { name, id, cdr_num, car, evaled } => write!(f, "{:?}({:?}{}{}{})", name, id, cdr_num, car, evaled), MarkedForm::SuspendedParamLookup { hash, name, id, cdr_num, car, evaled } => write!(f, "{:?}({:?}{}{}{})", name, id, cdr_num, car, evaled),
MarkedForm::PrimComb { name, wrap_level, .. } => write!(f, "<{}{}>", name, wrap_level), MarkedForm::PrimComb { name, wrap_level, .. } => write!(f, "<{}{}>", name, wrap_level),
//MarkedForm::DeriComb { ids, se, de, id, wrap_level, sequence_params, rest_params, body } => write!(f, "{:?}#[{}/{:?}/{:?}/{}/{:?}/{:?}/{}]", ids, se, de, id, wrap_level, sequence_params, rest_params, body), MarkedForm::DeriComb { hash, lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body } => {
MarkedForm::DeriComb { lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body } => {
//let env_form = format!("{}", se); //let env_form = format!("{}", se);
write!(f, "{}#[{:?}/{:?}/{:?}/{}/{:?}/{:?}/{}]", ids, lookup_name, de, id, wrap_level, sequence_params, rest_params, body) write!(f, "{}#[{:?}/{:?}/{:?}/{}/{:?}/{:?}/{}]", ids, lookup_name, de, id, wrap_level, sequence_params, rest_params, body)
}, },
MarkedForm::SuspendedPair{ ids, env, car, cdr } => { MarkedForm::SuspendedPair{ hash, ids, env, car, cdr } => {
if env.is_some() { if env.is_some() {
write!(f, "{}#HasEnv{{{}", ids, car)?; write!(f, "{}#HasEnv{{{}", ids, car)?;
} else { } else {
@@ -1235,7 +1265,7 @@ impl fmt::Display for MarkedForm {
let mut traverse: Rc<MarkedForm> = Rc::clone(cdr); let mut traverse: Rc<MarkedForm> = Rc::clone(cdr);
loop { loop {
match &*traverse { match &*traverse {
MarkedForm::Pair( ref ids, ref carp, ref cdrp) => { MarkedForm::Pair( ref h, ref ids, ref carp, ref cdrp) => {
write!(f, " {}", carp)?; write!(f, " {}", carp)?;
traverse = Rc::clone(cdrp); traverse = Rc::clone(cdrp);
}, },