Work on saving env on calls and suspended symbols, only use as env if legal. Seemingly causing exponential behavior, need to have it done incrementally... todo

This commit is contained in:
2023-03-29 01:58:07 -04:00
parent 8fa7acbdf1
commit 3c5bb127e2
4 changed files with 120 additions and 47 deletions

View File

@@ -314,10 +314,10 @@ pub enum MarkedForm {
Symbol(String),
Pair(NeededIds, Rc<MarkedForm>,Rc<MarkedForm>),
SuspendedSymbol(NeededIds, String), // Needs IDs if Env chains into suspended
SuspendedSymbol(Option<Rc<MarkedForm>>, String), // Needs IDs if Env chains into suspended
SuspendedParamLookup { name: Option<String>, id: EnvID, cdr_num: i32, car: bool, evaled: bool },
SuspendedEnvLookup { name: Option<String>, id: EnvID },
SuspendedPair { ids: NeededIds, car: Rc<MarkedForm>, cdr: Rc<MarkedForm>},
SuspendedPair { ids: NeededIds, env: Option<Rc<MarkedForm>>, car: Rc<MarkedForm>, cdr: Rc<MarkedForm>},
SuspendedEnvEval { ids: NeededIds, x: Rc<MarkedForm>, e: Rc<MarkedForm> },
SuspendedIf { ids: NeededIds, c: Rc<MarkedForm>, t: Rc<MarkedForm>, e: Rc<MarkedForm> },
@@ -334,7 +334,7 @@ impl MarkedForm {
let new_ids = car.ids().union(&cdr.ids());
Rc::new(MarkedForm::Pair(new_ids, car, cdr))
}
pub fn new_suspended_pair(attempted: Option<NeededIds>, car: Rc<MarkedForm>, cdr: Rc<MarkedForm>, under_body: Option<EnvID>, 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_body: Option<EnvID>, under_if: Option<EnvID>) -> Rc<MarkedForm> {
// differentiate between call and if rec_under
let ids = car.ids().union(&cdr.ids());
let ids = if let Some(attempted) = attempted {
@@ -344,8 +344,9 @@ impl MarkedForm {
};
let ids = if let Some(rec_under) = under_body { ids.add_body_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 };
Rc::new(MarkedForm::SuspendedPair{ ids, car, cdr })
Rc::new(MarkedForm::SuspendedPair{ ids, env, car, cdr })
}
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);
@@ -387,7 +388,7 @@ impl MarkedForm {
MarkedForm::Bool(b) => NeededIds::new_none(),
MarkedForm::Symbol(s) => NeededIds::new_none(),
MarkedForm::Pair(ids,car,cdr) => ids.clone(),
MarkedForm::SuspendedSymbol(ids, name) => ids.clone(),
MarkedForm::SuspendedSymbol(sus, name) => if let Some(sus) = sus { sus.ids() } else { NeededIds::new_true() },
MarkedForm::SuspendedEnvLookup { id, .. } => NeededIds::new_single(id.clone()),
MarkedForm::SuspendedParamLookup { id, .. } => NeededIds::new_single(id.clone()),
MarkedForm::SuspendedEnvEval { ids, ..} => ids.clone(),
@@ -404,7 +405,7 @@ impl MarkedForm {
MarkedForm::Int(i) => return true,
MarkedForm::Bool(b) => return true,
MarkedForm::Symbol(s) => return true,
MarkedForm::SuspendedSymbol(ids, name) => return false,
MarkedForm::SuspendedSymbol(sus, name) => return false,
MarkedForm::SuspendedEnvLookup { id, .. } => return false,
MarkedForm::SuspendedParamLookup { id, .. } => return false,
MarkedForm::SuspendedEnvEval { ids, ..} => return false,
@@ -439,9 +440,9 @@ impl MarkedForm {
MarkedForm::Nil => Ok(Rc::clone(self)),
MarkedForm::Int(i) => Ok(Rc::clone(self)),
MarkedForm::Bool(b) => Ok(Rc::clone(self)),
MarkedForm::Symbol(s) => Ok(Rc::new(MarkedForm::SuspendedSymbol(NeededIds::new_true(), s.clone()))),
MarkedForm::Pair(ids,car,cdr) => Ok(MarkedForm::new_suspended_pair(Some(NeededIds::new_true()), car.unval()?, Rc::clone(cdr), None, None)),
MarkedForm::SuspendedSymbol(ids, name) => bail!("trying to unval a suspended symbol"),
MarkedForm::Symbol(s) => Ok(Rc::new(MarkedForm::SuspendedSymbol(None, s.clone()))),
MarkedForm::Pair(ids,car,cdr) => Ok(MarkedForm::new_suspended_pair(None, Some(NeededIds::new_true()), car.unval()?, Rc::clone(cdr), None, None)),
MarkedForm::SuspendedSymbol(sus, name) => bail!("trying to unval a suspended symbol"),
MarkedForm::SuspendedEnvLookup { .. } => bail!("trying to unval a suspended env lookup"),
MarkedForm::SuspendedParamLookup { .. } => bail!("trying to unval a suspended param lookup"),
MarkedForm::SuspendedEnvEval { .. } => bail!("trying to unval a suspended env eval"),
@@ -451,6 +452,38 @@ impl MarkedForm {
MarkedForm::DeriComb { .. } => Ok(Rc::clone(self)),
}
}
pub fn is_legal_env_chain(&self) -> Result<bool> {
match self {
MarkedForm::Nil => Ok(true),
MarkedForm::Pair(ids,car,cdr) => {
match &**car {
MarkedForm::Pair(idsp,carp,cdrp) => {
match &**cdrp {
MarkedForm::SuspendedSymbol(sus, name) => Ok(false),
MarkedForm::SuspendedEnvEval { .. } => Ok(false),
MarkedForm::SuspendedIf { .. } => Ok(false),
MarkedForm::SuspendedPair{ ids, .. } => Ok(false),
_ => Ok(carp.is_sym() && cdr.is_legal_env_chain()?),
}
},
_ => Ok(false)
}
},
MarkedForm::SuspendedSymbol(sus, name) => Ok(false),
MarkedForm::SuspendedEnvLookup { .. } => Ok(false),
MarkedForm::SuspendedParamLookup { .. } => Ok(false),
MarkedForm::SuspendedEnvEval { .. } => Ok(false),
MarkedForm::SuspendedIf { .. } => Ok(false),
MarkedForm::SuspendedPair{ ids, .. } => Ok(false),
MarkedForm::Int(i) => bail!("bad env {}", self),
MarkedForm::Bool(b) => bail!("bad env {}", self),
MarkedForm::Symbol(s) => bail!("bad env {}", self),
MarkedForm::PrimComb { .. } => bail!("bad env {}", self),
MarkedForm::DeriComb { .. } => bail!("bad env {}", self),
}
}
pub fn truthy(&self) -> Result<bool> {
match self {
MarkedForm::Nil => Ok(false),
@@ -458,7 +491,7 @@ impl MarkedForm {
MarkedForm::Bool(b) => Ok(*b),
MarkedForm::Symbol(s) => Ok(true),
MarkedForm::Pair(ids,car,cdr) => Ok(true),
MarkedForm::SuspendedSymbol(ids, name) => bail!("trying to truthy a suspended symbol"),
MarkedForm::SuspendedSymbol(sus, name) => bail!("trying to truthy a suspended symbol"),
MarkedForm::SuspendedEnvLookup { .. } => bail!("trying to truthy a suspended env lookup"),
MarkedForm::SuspendedParamLookup { .. } => bail!("trying to truthy a suspended param lookup"),
MarkedForm::SuspendedEnvEval { .. } => bail!("trying to truthy a suspended env eval"),
@@ -468,6 +501,12 @@ impl MarkedForm {
MarkedForm::DeriComb { .. } => Ok(true),
}
}
pub fn is_sym(&self) -> bool {
match self {
MarkedForm::Symbol(s) => true,
_ => false,
}
}
pub fn sym(&self) -> Result<&str> {
match self {
MarkedForm::Symbol(s) => Ok(s),
@@ -511,7 +550,7 @@ fn eval_func(bctx: BCtx, dctx: DCtx, p: Rc<MarkedForm>) -> Result<(BCtx,Rc<Marke
return Ok((bctx, Rc::new(MarkedForm::SuspendedParamLookup { name: name.clone(), id: id.clone(), cdr_num: *cdr_num, car: *car, evaled: true })));
}
}
Ok((bctx, MarkedForm::new_suspended_pair( Some(x.ids()), make_eval_prim(0), p, None, None )))
Ok((bctx, MarkedForm::new_suspended_pair( None, Some(x.ids()), make_eval_prim(0), p, None, None )))
} else {
//println!("Ok, returning new suspended env eval with");
//println!("\t{} {}", p.car()?.unval()?, p.cdr()?.car()?);
@@ -533,9 +572,9 @@ fn cons_func(bctx: BCtx, dctx: DCtx, p: Rc<MarkedForm>) -> Result<(BCtx,Rc<Marke
let h = p.car()?;
let t = p.cdr()?.car()?;
if !(h.is_value() || h.is_pair()) {
Ok((bctx, MarkedForm::new_suspended_pair(Some(h.ids()), make_cons_prim(0), p, None, None)))
Ok((bctx, MarkedForm::new_suspended_pair(None, Some(h.ids()), make_cons_prim(0), p, None, None)))
} else if !(t.is_value() || t.is_pair() || t.is_suspended_param() || t.is_suspended_env()) {
Ok((bctx, MarkedForm::new_suspended_pair(Some(t.ids()), make_cons_prim(0), p, None, None)))
Ok((bctx, MarkedForm::new_suspended_pair(None, Some(t.ids()), make_cons_prim(0), p, None, None)))
} else {
Ok((bctx, MarkedForm::new_pair(h, t)))
}
@@ -547,7 +586,7 @@ fn car_func(bctx: BCtx, dctx: DCtx, p: Rc<MarkedForm>) -> Result<(BCtx,Rc<Marked
let maybe_pair = p.car()?;
match maybe_pair.car() {
Ok(x) => Ok((bctx, x)),
Err(_) => Ok((bctx, MarkedForm::new_suspended_pair(Some(maybe_pair.ids()), make_car_prim(0), p, None, None))),
Err(_) => Ok((bctx, MarkedForm::new_suspended_pair(None, Some(maybe_pair.ids()), make_car_prim(0), p, None, None))),
}
}
fn make_cdr_prim(wrap_level: i32) -> Rc<MarkedForm> {
@@ -557,7 +596,7 @@ fn cdr_func(bctx: BCtx, dctx: DCtx, p: Rc<MarkedForm>) -> Result<(BCtx,Rc<Marked
let maybe_pair = p.car()?;
match maybe_pair.cdr() {
Ok(x) => Ok((bctx, x)),
Err(_) => Ok((bctx, MarkedForm::new_suspended_pair(Some(maybe_pair.ids()), make_cdr_prim(0), p, None, None))),
Err(_) => Ok((bctx, MarkedForm::new_suspended_pair(None, Some(maybe_pair.ids()), make_cdr_prim(0), p, None, None))),
}
}
@@ -568,7 +607,8 @@ fn make_debug_prim() -> Rc<MarkedForm> {
fn debug_func(bctx: BCtx, dctx: DCtx, p: Rc<MarkedForm>) -> Result<(BCtx,Rc<MarkedForm>)> {
// This one is a bit weird - we put the wrap level at 1 so both sides are pe'd,
// and then return runtime
Ok((bctx, MarkedForm::new_suspended_pair( Some(NeededIds::new_single(runtime_id.clone())), make_debug_prim(), p, None, None )))
// Hmm, I do wonder if it should capture ENV for debugging purposes
Ok((bctx, MarkedForm::new_suspended_pair( None, Some(NeededIds::new_single(runtime_id.clone())), make_debug_prim(), p, None, None )))
}
pub fn mark(form: Rc<Form>, bctx: BCtx) -> (BCtx, Rc<MarkedForm>) {
@@ -762,8 +802,10 @@ pub fn partial_eval(bctx_in: BCtx, dctx_in: DCtx, form: Rc<MarkedForm>) -> Resul
// Nowadays, dropping EnvEval is legal always *unless*
// - True is in ids
// - this current env ends in a suspended param/env, and that id is in ids (the *weird* case)
// GAH FIXED THIS WITH THE SUSPENDED THING BUT NOW THE SAME PROBLEM HAPPENS FOR
// SUSPENDED CALLS THAT TAKE IN THE DE
if let MarkedForm::SuspendedEnvEval { x, e, .. } = &*new_form {
if !x.ids().may_contain_id(&true_id) {
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: {}", "", x, ident=dctx.ident*4);
next_form = Some(Rc::clone(x));
@@ -809,7 +851,7 @@ fn map_unval_peval(bctx: BCtx, dctx: DCtx, x: Rc<MarkedForm>) -> MapUnvalPEvalRe
MarkedForm::Pair(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::SuspendedSymbol(ids, name) => MapUnvalPEvalResult::NotYet(anyhow!("map_unval_peval over not (yet) a list")),
MarkedForm::SuspendedSymbol(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::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")),
@@ -827,11 +869,15 @@ fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &mut DCtx) -> Result<
let (bctx, cdr) = partial_eval(bctx, dctx.clone(), Rc::clone(cdr))?;
Ok((bctx, MarkedForm::new_pair(car, cdr)))
},
MarkedForm::SuspendedSymbol(ids, name) => {
MarkedForm::SuspendedSymbol(sus, name) => {
// 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 {} in {}", name, dctx.e);
let mut t = Rc::clone(&dctx.e);
//println!("Lookin up symbol {}", name);
println!("Lookin up symbol {} in {}", name, dctx.e);
let (bctx, mut t) = if let Some(sus) = sus {
partial_eval(bctx, dctx.clone(), Rc::clone(sus))?
} else {
(bctx, Rc::clone(&dctx.e))
};
loop {
if let Ok(cmp) = t.car().and_then(|kv| kv.car()).and_then(|s| s.sym().map(|s| s.to_owned())) {
if *name == cmp {
@@ -844,7 +890,7 @@ fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &mut DCtx) -> Result<
// bad env
match &*t {
MarkedForm::Nil => bail!("Lookup for {} not found!", name),
MarkedForm::SuspendedSymbol(ids, name) => break,
MarkedForm::SuspendedSymbol(sus, name) => break,
MarkedForm::SuspendedEnvLookup { .. } => break,
MarkedForm::SuspendedParamLookup { .. } => break,
MarkedForm::SuspendedEnvEval { .. } => break,
@@ -856,7 +902,7 @@ fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &mut DCtx) -> Result<
}
}
println!("\tcouldn't find it, returning suspended");
return Ok((bctx, Rc::new(MarkedForm::SuspendedSymbol(t.ids(), name.clone()))));
return Ok((bctx, Rc::new(MarkedForm::SuspendedSymbol(Some(t), name.clone()))));
},
MarkedForm::SuspendedEnvLookup { name, id } => {
if let Some(v) = dctx.sus_env_stack.get(id) {
@@ -888,11 +934,15 @@ fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &mut DCtx) -> Result<
// this bit is a little tricky - we'd like to tail call, but we can't lose our env
// if it fails.
let (bctx, e) = partial_eval(bctx, dctx.clone(), Rc::clone(e))?;
let (bctx, x) = partial_eval(bctx, dctx.copy_set_env(&e), Rc::clone(x))?;
if x.is_value() {
Ok((bctx, x))
if !e.is_legal_env_chain()? {
Ok((bctx, MarkedForm::new_suspended_env_eval(Rc::clone(x), e)))
} else {
Ok((bctx, MarkedForm::new_suspended_env_eval(x, e)))
let (bctx, x) = partial_eval(bctx, dctx.copy_set_env(&e), Rc::clone(x))?;
if x.is_value() {
Ok((bctx, x))
} else {
Ok((bctx, MarkedForm::new_suspended_env_eval(x, e)))
}
}
// Note also that we drop redundent vevals at the bottom of the loop tail-call loop
// with force
@@ -952,7 +1002,13 @@ fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &mut DCtx) -> Result<
},
}
},
MarkedForm::SuspendedPair { ids, car, cdr } => {
MarkedForm::SuspendedPair { ids, env, car, cdr } => {
let ( bctx, mut env) = if let Some(env) = env {
partial_eval(bctx, dctx.clone(), Rc::clone(env))?
} else {
(bctx, Rc::clone(&dctx.e))
};
let mut need_denv = true;
let ( bctx, mut car) = partial_eval(bctx, dctx.clone(), Rc::clone(car))?;
let (mut bctx, mut cdr) = partial_eval(bctx, dctx.clone(), Rc::clone(cdr))?;
while let Some(wrap_level) = car.wrap_level() {
@@ -979,18 +1035,21 @@ fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &mut DCtx) -> Result<
// We might want to enable not pure values for cons/car/cdr?
match &*car {
MarkedForm::PrimComb { name, nonval_ok, takes_de, wrap_level, f} => {
need_denv = *takes_de;
if !nonval_ok && !cdr.is_value() {
break;
}
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);
//return f(bctx.clone(), dctx.clone(), Rc::clone(&cdr));
let (bctx,result) = f(bctx.clone(), dctx.clone(), 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", "", ident=dctx.ident*4);
return Ok((bctx,result));
}
MarkedForm::DeriComb { lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body } => {
need_denv = de.is_some();
let saved_env = if need_denv { Some(Rc::clone(&env)) } else { None };
if !cdr.is_value() {
break;
}
@@ -1001,10 +1060,11 @@ fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &mut DCtx) -> Result<
// environment we will replace it with our real environment that
// still has a dynamic reference to the current environment, which
// will be an infinate loop
return Ok((bctx, MarkedForm::new_suspended_pair( Some(NeededIds::new_single(id.clone())), car, cdr, None, None)));
let saved_env = if need_denv { Some(Rc::clone(&env)) } else { None };
return Ok((bctx, MarkedForm::new_suspended_pair( saved_env, Some(NeededIds::new_single(id.clone())), car, cdr, None, None)));
}
// not yet supporting sequence params
match dctx.copy_push_frame(id.clone(), &se, &de, Some(Rc::clone(&dctx.e)), &rest_params, Some(Rc::clone(&cdr)), body) {
match dctx.copy_push_frame(id.clone(), &se, &de, Some(Rc::clone(&env)), &rest_params, Some(Rc::clone(&cdr)), body) {
PushFrameResult::Ok(inner_dctx) => {
let ident_amount = inner_dctx.ident*4;
//println!("{:ident$}doing a call eval of {} in {}", "", body, inner_dctx.e, ident=inner_dctx.ident*4);
@@ -1017,16 +1077,16 @@ fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &mut DCtx) -> Result<
if combiner_return_ok(&r, Some(id.clone())) {
return Ok((bctx, r));
} else {
return Ok((bctx, MarkedForm::new_suspended_pair( Some(r.ids()), car, cdr, None, None)));
return Ok((bctx, MarkedForm::new_suspended_pair( saved_env, Some(r.ids()), car, cdr, None, None)));
}
},
PushFrameResult::UnderBody(rec_stop_under) => {
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( None, car, cdr, Some(rec_stop_under), None)));
return Ok((bctx, MarkedForm::new_suspended_pair( saved_env, None, car, cdr, Some(rec_stop_under), None)));
},
PushFrameResult::UnderIf(rec_stop_under) => {
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( None, car, cdr, None, Some(rec_stop_under))));
return Ok((bctx, MarkedForm::new_suspended_pair( saved_env, None, car, cdr, None, Some(rec_stop_under))));
},
}
},
@@ -1045,7 +1105,7 @@ fn partial_eval_step(x: &Rc<MarkedForm>, bctx: BCtx, dctx: &mut DCtx) -> Result<
}
}
// Didn't manage to call
Ok((bctx, MarkedForm::new_suspended_pair( None, car, cdr, None, None)))
Ok((bctx, MarkedForm::new_suspended_pair( if need_denv { Some(env) } else { None }, None, car, cdr, None, None)))
},
// Values should never get here b/c ids UNLESS FORCE HAH
_ => panic!("value evaled! {}", x),
@@ -1082,7 +1142,7 @@ impl fmt::Display for MarkedForm {
},
MarkedForm::SuspendedEnvEval { ids, x, e } => write!(f, "({}){{Sveval {} {}}}", ids, x, e),
MarkedForm::SuspendedIf { ids, c, t, e } => write!(f, "({}){{Sif {} {} {}}}", ids, c, t, e),
MarkedForm::SuspendedSymbol(ids,name) => write!(f, "({}){}", ids, name),
MarkedForm::SuspendedSymbol(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::SuspendedParamLookup { name, id, cdr_num, car, evaled } => write!(f, "{:?}({:?}{}{}{})", name, id, cdr_num, car, evaled),
MarkedForm::PrimComb { name, wrap_level, .. } => write!(f, "<{}{}>", name, wrap_level),
@@ -1093,8 +1153,12 @@ impl fmt::Display for MarkedForm {
write!(f, "{}#[{:?}/{:?}/{:?}/{}/{:?}/{:?}/{}]", ids, lookup_name, de, id, wrap_level, sequence_params, rest_params, body)
},
MarkedForm::SuspendedPair{ ids, car, cdr } => {
write!(f, "{}#{{{}", ids, car)?;
MarkedForm::SuspendedPair{ ids, env, car, cdr } => {
if env.is_some() {
write!(f, "{}#HasEnv{{{}", ids, car)?;
} else {
write!(f, "{}#{{{}", ids, car)?;
}
//write!(f, "{{{}", car)?;
let mut traverse: Rc<MarkedForm> = Rc::clone(cdr);
loop {

View File

@@ -50,9 +50,15 @@ fn partial_eval_test(gram: &grammar::TermParser, code: &str, expected: &str) {
fn basic_pe_test() {
let g = grammar::TermParser::new();
partial_eval_test(&g, "(+ 2 (car (cons 4 '(1 2))))", "6");
partial_eval_test(&g, "(vau 0 p (+ 1 2))", "NeededIds { heads: {}, tails: {}, body_stopped: {}, if_stopped: {} }#[None/None/EnvID(1)/0/[]/Some(\"p\")/3]");
partial_eval_test(&g, "(vau 0 p (+ 1 2))", "NeedsNone#[None/None/EnvID(1)/0/[]/Some(\"p\")/3]");
partial_eval_test(&g, "(vau de p (+ (eval (car p) de) (eval (car (cdr p)) de)))", "NeededIds { heads: {}, tails: {}, body_stopped: {}, if_stopped: {} }#[None/Some(\"de\")/EnvID(1)/0/[]/Some(\"p\")/NeededIds { heads: {EnvID(1)}, tails: {}, body_stopped: {}, if_stopped: {} }#{<+0> NeededIds { heads: {EnvID(1)}, tails: {}, body_stopped: {}, if_stopped: {} }#{<eval0> Some(\"p\")(EnvID(1)0true) Some(\"de\")(EnvID(1)env)} NeededIds { heads: {EnvID(1)}, tails: {}, body_stopped: {}, if_stopped: {} }#{<eval0> Some(\"p\")(EnvID(1)1true) Some(\"de\")(EnvID(1)env)}}]");
partial_eval_test(&g, "(vau de p (+ (eval (car p) de) (eval (car (cdr p)) de)))", "NeedsNone#[None/Some(\"de\")/EnvID(1)/0/[]/Some(\"p\")/NeedsH{EnvID(1)}#{<+0> Some(\"p\")(EnvID(1)0truetrue) Some(\"p\")(EnvID(1)1truetrue)}]");
partial_eval_test(&g, "(vau de p (eval '(+ a 2) (cons (cons 'a (eval (car p) de))
((vau de p de)))))", "NeedsNone#[None/Some(\"de\")/EnvID(1)/0/[]/Some(\"p\")/NeedsH{EnvID(1)}#{<+0> Some(\"a\")(EnvID(1)0truetrue) 2}]");
//partial_eval_test(&g, "(vau de p (eval (+ a b) (cons (cons 'a (eval (car p) de))
// (cons (cons 'b (eval (car (cdr p)) de))
// de))))", "");
}
#[test]
@@ -118,16 +124,16 @@ static LET: Lazy<String> = Lazy::new(|| {
fn let_pe_test() {
let g = grammar::TermParser::new();
partial_eval_test(&g, &format!("{} (let1 a 2 (+ a (car (cons 4 '(1 2)))))", *LET), "6");
partial_eval_test(&g, &format!("{} (let1 a 2 (vau 0 p (+ 1 a)))", *LET),"NeededIds { heads: {}, tails: {}, body_stopped: {}, if_stopped: {} }#[None/None/EnvID(3)/0/[]/Some(\"p\")/3]");
partial_eval_test(&g, &format!("{} (let1 a 2 (vau 0 p (+ 1 a)))", *LET),"NeedsNone#[None/None/EnvID(3)/0/[]/Some(\"p\")/3]");
partial_eval_test(&g, &format!("{}
!(let1 a 2)
(vau 0 p (+ 1 a))
", *LET), "NeededIds { heads: {}, tails: {}, body_stopped: {}, if_stopped: {} }#[None/None/EnvID(3)/0/[]/Some(\"p\")/3]");
", *LET), "NeedsNone#[None/None/EnvID(3)/0/[]/Some(\"p\")/3]");
partial_eval_test(&g, &format!("{}
!(let1 a 2)
!(let1 b 5)
(vau 0 p (+ b a))
", *LET), "NeededIds { heads: {}, tails: {}, body_stopped: {}, if_stopped: {} }#[None/None/EnvID(3)/0/[]/Some(\"p\")/7]");
", *LET), "NeedsNone#[None/None/EnvID(3)/0/[]/Some(\"p\")/7]");
/*
partial_eval_test(&g, &format!("{}
(vau 0 p

View File

@@ -2,8 +2,8 @@
<html lang="en-us">
<meta charset="UTF-8">
<head>
<link id="theme" rel="stylesheet" type="text/css" href="slick.css"/>
<!--<link id="theme" rel="stylesheet" type="text/css" href="recursive.css"/>-->
<!--<link id="theme" rel="stylesheet" type="text/css" href="slick.css"/>-->
<link id="theme" rel="stylesheet" type="text/css" href="recursive.css"/>
</head>
<body>
<header><h1>Kraken</h1></header>

View File

@@ -29,7 +29,10 @@ body {
h1, h2, h3, h4 {
line-height:1.2;
--rec-wght: 700;
--rec-casl: 1;
//--rec-casl: 1;
--rec-casl: 0.5;
//--rec-casl: 0;
//--rec-mono: 1;
--rec-crsv: 1;
}
h1 {