Too much debugging to find out PE assert was broken and debugging printlns were overflowing the stack. Some of the other tests also overflow the stack if not built in release mode, and I disabled the stack-testing tests for PE

This commit is contained in:
2023-02-21 10:32:26 -05:00
parent 67feab10bc
commit 21fb47470a
2 changed files with 84 additions and 43 deletions

View File

@@ -109,7 +109,7 @@ impl Form {
// and veval // and veval
let b = p.car()?.unval()?; let b = p.car()?.unval()?;
let e = p.cdr()?.car()?; let e = p.cdr()?.car()?;
println!("Doing Eval (via tail call) of {} in {}", b, e); //println!("Doing Eval (via tail call) of {} in {}", b, e);
Ok((bctx, PossibleMarkedTailCall::TailCall(e, b))) Ok((bctx, PossibleMarkedTailCall::TailCall(e, b)))
}}), }}),
"vau" => Rc::new(MarkedForm::PrimComb { name: "vau".to_owned(), takes_de: true, wrap_level: 0, f: |bctx, dctx, p| { "vau" => Rc::new(MarkedForm::PrimComb { name: "vau".to_owned(), takes_de: true, wrap_level: 0, f: |bctx, dctx, p| {
@@ -125,7 +125,7 @@ impl Form {
// //
let inner_dctx = dctx.copy_push_frame(id.clone(), &se, &de, None, &rest_params, None, &body).unwrap(); let inner_dctx = dctx.copy_push_frame(id.clone(), &se, &de, None, &rest_params, None, &body).unwrap();
let (bctx, body) = partial_eval(bctx, inner_dctx, Rc::clone(&body))?; let (bctx, body) = partial_eval(bctx, inner_dctx, Rc::clone(&body))?;
Ok((bctx, PossibleMarkedTailCall::Result(MarkedForm::new_deri_comb( se, de, id, wrap_level, sequence_params, rest_params, body )))) Ok((bctx, PossibleMarkedTailCall::Result(MarkedForm::new_deri_comb( se, None, de, id, wrap_level, sequence_params, rest_params, body ))))
}}), }}),
// TODO: handle vif, partial eval branches // TODO: handle vif, partial eval branches
"if" => Rc::new(MarkedForm::PrimComb { name: "if".to_owned(), takes_de: true, wrap_level: 0, f: |bctx, dctx, p| { "if" => Rc::new(MarkedForm::PrimComb { name: "if".to_owned(), takes_de: true, wrap_level: 0, f: |bctx, dctx, p| {
@@ -161,20 +161,22 @@ impl Form {
}}), }}),
// ditto // ditto
"assert" => Rc::new(MarkedForm::PrimComb { name: "assert".to_owned(), takes_de: true, wrap_level: 0, f: |bctx, dctx, p| { "assert" => Rc::new(MarkedForm::PrimComb { name: "assert".to_owned(), takes_de: true, wrap_level: 0, f: |bctx, dctx, p| {
panic!(); //panic!();
println!("Assert test {:?}", p.car());
let (bctx, cond) = partial_eval(bctx, dctx.clone(), p.car()?.unval()?)?; let (bctx, cond) = partial_eval(bctx, dctx.clone(), p.car()?.unval()?)?;
println!("\tAssert result {}", cond);
if !cond.truthy()? { if !cond.truthy()? {
println!("Assert failed: {:?}", cond); println!("Assert failed: {:?}", cond);
} }
assert!(cond.truthy()?); assert!(cond.truthy()?);
let e = Rc::clone(&dctx.e); let e = Rc::clone(&dctx.e);
Ok((bctx, PossibleMarkedTailCall::TailCall(e, p.cdr()?.car()?))) Ok((bctx, PossibleMarkedTailCall::TailCall(e, p.cdr()?.car()?.unval()?)))
}}), }}),
// (vau de params body), should be able to take in wrap_level != 1 and do stuff // (vau de params body), should be able to take in wrap_level != 1 and do stuff
"=" => Rc::new(MarkedForm::PrimComb { name: "=".to_owned(), takes_de: false, wrap_level: 1, f: |bctx, dctx, p| { "=" => Rc::new(MarkedForm::PrimComb { name: "=".to_owned(), takes_de: false, wrap_level: 1, f: |bctx, dctx, p| {
let a = p.car()?; let a = p.car()?;
let b = p.cdr()?.car()?; let b = p.cdr()?.car()?;
println!("DOing (= {} {}) = {}", a, b, a==b); //println!("DOing (= {} {}) = {}", a, b, a==b);
// TODO: double check that this ignores ids etc. It should, since // TODO: double check that this ignores ids etc. It should, since
// wrap_level=1 should mean that everything's a value // wrap_level=1 should mean that everything's a value
// also, it should just check by hash then? // also, it should just check by hash then?
@@ -562,10 +564,10 @@ pub fn combiner_return_ok(x: Rc<MarkedForm>, check_id: EnvID) -> bool {
} }
pub fn partial_eval(bctx: BCtx, dctx: DCtx, x: Rc<MarkedForm>) -> Result<(BCtx,Rc<MarkedForm>), String> { pub fn partial_eval(bctx: BCtx, dctx: DCtx, x: Rc<MarkedForm>) -> Result<(BCtx,Rc<MarkedForm>), String> {
println!("{:ident$}PE: {}", "", x, ident=dctx.ident*4); //println!("{:ident$}PE: {}", "", x, ident=dctx.ident*4);
let should_go = dctx.force || dctx.can_progress(x.ids()); let should_go = dctx.force || dctx.can_progress(x.ids());
if !should_go { if !should_go {
println!("{:ident$}Shouldn't go!", "", ident=dctx.ident*4); //println!("{:ident$}Shouldn't go!", "", ident=dctx.ident*4);
return Ok((bctx, x)); return Ok((bctx, x));
} }
match &*x { match &*x {
@@ -574,18 +576,26 @@ pub fn partial_eval(bctx: BCtx, dctx: DCtx, x: Rc<MarkedForm>) -> Result<(BCtx,R
while name != t.car()?.car()?.sym()? { while name != t.car()?.car()?.sym()? {
t = t.cdr()?; t = t.cdr()?;
} }
return Ok((bctx, t.car()?.cdr()?)); Ok((bctx, t.car()?.cdr()?.tag_name(name)))
}, },
MarkedForm::SuspendedEnvLookup { name, id } => { MarkedForm::SuspendedEnvLookup { name, id } => {
if let Some(v) = dctx.sus_env_stack.get(id) { if let Some(v) = dctx.sus_env_stack.get(id) {
if let Some(name) = name {
Ok((bctx, v.tag_name(name)))
} else {
Ok((bctx, Rc::clone(v))) Ok((bctx, Rc::clone(v)))
}
} else { } else {
Ok((bctx, x)) Ok((bctx, x))
} }
}, },
MarkedForm::SuspendedParamLookup { name, id, cdr_num, car } => { MarkedForm::SuspendedParamLookup { name, id, cdr_num, car } => {
if let Some(v) = dctx.sus_prm_stack.get(id) { if let Some(v) = dctx.sus_prm_stack.get(id) {
if let Some(name) = name {
Ok((bctx, v.tag_name(name)))
} else {
Ok((bctx, Rc::clone(v))) Ok((bctx, Rc::clone(v)))
}
} else { } else {
Ok((bctx, x)) Ok((bctx, x))
} }
@@ -624,38 +634,62 @@ pub fn partial_eval(bctx: BCtx, dctx: DCtx, x: Rc<MarkedForm>) -> Result<(BCtx,R
match &*car { match &*car {
MarkedForm::PrimComb { name, takes_de, wrap_level, f} => { MarkedForm::PrimComb { name, takes_de, wrap_level, f} => {
new_attempted = Attempted::True(if *takes_de { Some(dctx.e.ids()) } else { None }); new_attempted = Attempted::True(if *takes_de { Some(dctx.e.ids()) } else { None });
if let Ok((bctx, r)) = f(bctx.clone(), dctx.clone(), Rc::clone(&cdr)) { let ident_amount = dctx.ident*4;
//println!("{:ident$}doing a call eval of {}", "", name, ident=ident_amount);
match f(bctx.clone(), dctx.clone(), Rc::clone(&cdr)) {
Ok((bctx, r)) => {
match r { match r {
PossibleMarkedTailCall::Result(result) => return Ok((bctx, result)), PossibleMarkedTailCall::Result(result) => return Ok((bctx, result)),
// Sigh, no tail-callin right now // Sigh, no tail-callin right now
PossibleMarkedTailCall::TailCall(new_env, next) => { PossibleMarkedTailCall::TailCall(new_env, next) => {
println!("Doing tail call of {} in {}", next, new_env); //println!("{:ident$}doing a tail call of {} in {}", "", next, new_env, ident=ident_amount);
if let Ok((new_bctx, res)) = partial_eval(bctx.clone(), dctx.copy_set_env(&new_env), Rc::clone(&next)) { if let Ok((new_bctx, res)) = partial_eval(bctx.clone(), dctx.copy_set_env(&new_env), Rc::clone(&next)) {
println!("Doing tail call result is {}", res); //println!("{:ident$}doing a tail call result is {}", "", res, ident=ident_amount);
return Ok((new_bctx, res)); return Ok((new_bctx, res));
} else { } else {
println!("Tail call failed"); //println!("Tail call failed");
if new_env == dctx.e { if new_env == dctx.e {
//println!("{:ident$}Tail call failed, but can emplace", "", ident=ident_amount);
return Ok((bctx, next)); return Ok((bctx, next));
} else { } else {
//println!("{:ident$}Tail call failed, can't emplace", "", ident=ident_amount);
// maybe this should enplace the TailCall with an eval // maybe this should enplace the TailCall with an eval
break; // break out to reconstruction break; // break out to reconstruction
} }
} }
} }
} }
} else { break; } },
Err(msg) => {
//println!("{:ident$}failed {:?}", "", msg, ident=ident_amount);
break;
},
} }
MarkedForm::DeriComb { hash, 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 } => {
new_attempted = Attempted::True(if de.is_some() { Some(dctx.e.ids()) } else { None }); new_attempted = Attempted::True(if de.is_some() { Some(dctx.e.ids()) } else { None });
// not yet supporting sequence params // not yet supporting sequence params
// needs to check hash // needs to check hash
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(&dctx.e)), &rest_params, Some(Rc::clone(&cdr)), body) {
Ok(inner_dctx) => { Ok(inner_dctx) => {
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);
if let Ok((bctx, r)) = partial_eval(bctx.clone(), inner_dctx, Rc::clone(body)) { let ident_amount = inner_dctx.ident*4;
//println!("{:ident$}doing a call eval of {:?}", "", lookup_name, ident=ident_amount);
//if let Ok((bctx, r)) = partial_eval(bctx.clone(), inner_dctx, Rc::clone(body)) {
// if combiner_return_ok(Rc::clone(&r), id.clone()) {
// return Ok((bctx, r));
// }
//}
match partial_eval(bctx.clone(), inner_dctx, Rc::clone(body)) {
Ok((bctx, r)) => {
if combiner_return_ok(Rc::clone(&r), id.clone()) { if combiner_return_ok(Rc::clone(&r), id.clone()) {
return Ok((bctx, r)); return Ok((bctx, r));
} else {
//println!("{:ident$}combiner return not ok {}", "", r, ident=ident_amount);
}
}
Err(msg) => {
//println!("{:ident$}failed {:?}", "", msg, ident=ident_amount);
} }
} }
}, },
@@ -676,13 +710,13 @@ pub fn partial_eval(bctx: BCtx, dctx: DCtx, x: Rc<MarkedForm>) -> Result<(BCtx,R
let (bctx, cdr) = partial_eval(bctx, dctx, Rc::clone(cdr))?; let (bctx, cdr) = partial_eval(bctx, dctx, Rc::clone(cdr))?;
Ok((bctx, MarkedForm::new_pair(car, cdr))) Ok((bctx, MarkedForm::new_pair(car, cdr)))
}, },
MarkedForm::DeriComb { hash, 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 } => {
if !se.ids().needs_nothing() { if !se.ids().needs_nothing() {
// 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);
let inner_dctx = dctx.copy_push_frame(id.clone(), &se, &de, None, &rest_params, None, body).expect("Not sure if this can ever fail or not... maybe for Y comb recursion?"); let inner_dctx = dctx.copy_push_frame(id.clone(), &se, &de, None, &rest_params, None, body).expect("Not sure if this can ever fail or not... maybe for Y comb recursion?");
let (bctx, body) = partial_eval(bctx, inner_dctx, Rc::clone(&body))?; let (bctx, body) = partial_eval(bctx, inner_dctx, Rc::clone(&body))?;
Ok((bctx, MarkedForm::new_deri_comb( se, de.clone(), id.clone(), *wrap_level, sequence_params.clone(), rest_params.clone(), body ))) Ok((bctx, MarkedForm::new_deri_comb( se, lookup_name.clone(), de.clone(), id.clone(), *wrap_level, sequence_params.clone(), rest_params.clone(), body )))
} else { } else {
Ok((bctx, x)) Ok((bctx, x))
} }
@@ -711,7 +745,7 @@ pub enum MarkedForm {
SuspendedPair { hash: MFHash, ids: NeededIds, attempted: Attempted, car: Rc<MarkedForm>, cdr: Rc<MarkedForm>}, SuspendedPair { hash: MFHash, ids: NeededIds, attempted: Attempted, car: Rc<MarkedForm>, cdr: Rc<MarkedForm>},
PrimComb { name: String, takes_de: bool, wrap_level: i32, f: fn(BCtx,DCtx,Rc<MarkedForm>) -> Result<(BCtx,PossibleMarkedTailCall),String> }, PrimComb { name: String, takes_de: bool, wrap_level: i32, f: fn(BCtx,DCtx,Rc<MarkedForm>) -> Result<(BCtx,PossibleMarkedTailCall),String> },
DeriComb { hash: MFHash, ids: NeededIds, se: Rc<MarkedForm>, de: Option<String>, id: EnvID, wrap_level: i32, sequence_params: Vec<String>, rest_params: Option<String>, body: Rc<MarkedForm> }, DeriComb { hash: MFHash, 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> },
} }
impl MarkedForm { impl MarkedForm {
pub fn new_pair(car: Rc<MarkedForm>, cdr: Rc<MarkedForm>) -> Rc<MarkedForm> { pub fn new_pair(car: Rc<MarkedForm>, cdr: Rc<MarkedForm>) -> Rc<MarkedForm> {
@@ -737,12 +771,19 @@ impl MarkedForm {
} }
Rc::new(MarkedForm::SuspendedPair{ hash: MFHash(h.finish()), attempted, ids, car, cdr }) Rc::new(MarkedForm::SuspendedPair{ hash: MFHash(h.finish()), attempted, ids, car, cdr })
} }
pub fn new_deri_comb(se: Rc<MarkedForm>, de: Option<String>, id: EnvID, wrap_level: i32, sequence_params: Vec<String>, rest_params: Option<String>, body: Rc<MarkedForm>) -> 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>) -> Rc<MarkedForm> {
let mut h = DefaultHasher::new(); let mut h = DefaultHasher::new();
"DeriComb".hash(&mut h); se.hash().hash(&mut h); de.hash(&mut h); id.hash(&mut h); wrap_level.hash(&mut h); "DeriComb".hash(&mut h); se.hash().hash(&mut h); de.hash(&mut h); id.hash(&mut h); wrap_level.hash(&mut h);
sequence_params.hash(&mut h); rest_params.hash(&mut h); body.hash().hash(&mut h); sequence_params.hash(&mut h); rest_params.hash(&mut h); body.hash().hash(&mut h);
let ids = se.ids().union_without(&body.ids(), id.clone()); let ids = se.ids().union_without(&body.ids(), id.clone());
Rc::new(MarkedForm::DeriComb{ hash: MFHash(h.finish()), ids, se, de, id, wrap_level, sequence_params, rest_params, body }) Rc::new(MarkedForm::DeriComb{ hash: MFHash(h.finish()), lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body })
}
pub fn tag_name(self: &Rc<MarkedForm>, name: &str) -> Rc<MarkedForm> {
match &**self {
MarkedForm::DeriComb { hash, lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body } =>
MarkedForm::new_deri_comb(Rc::clone(se), Some(name.to_owned()), de.clone(), id.clone(), *wrap_level, sequence_params.clone(), rest_params.clone(), Rc::clone(body)),
_ => Rc::clone(self),
}
} }
pub fn hash(&self) -> MFHash { pub fn hash(&self) -> MFHash {
let mut h = DefaultHasher::new(); let mut h = DefaultHasher::new();
@@ -774,7 +815,7 @@ 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, takes_de, wrap_level, f } => Some(Rc::new(MarkedForm::PrimComb { name: name.clone(), takes_de: *takes_de, wrap_level: wrap_level-1, f: *f })), MarkedForm::PrimComb { name, takes_de, wrap_level, f } => Some(Rc::new(MarkedForm::PrimComb { name: name.clone(), takes_de: *takes_de, wrap_level: wrap_level-1, f: *f })),
MarkedForm::DeriComb { hash, ids, se, de, id, wrap_level, sequence_params, rest_params, body } => Some(MarkedForm::new_deri_comb(Rc::clone(se), de.clone(), id.clone(), wrap_level-1, sequence_params.clone(), rest_params.clone(), Rc::clone(body))), MarkedForm::DeriComb { hash, lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body } => Some(MarkedForm::new_deri_comb(Rc::clone(se), lookup_name.clone(), de.clone(), id.clone(), wrap_level-1, sequence_params.clone(), rest_params.clone(), Rc::clone(body))),
_ => None, _ => None,
} }
} }
@@ -902,7 +943,7 @@ impl fmt::Display for MarkedForm {
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 { 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, ids, se, de, id, wrap_level, sequence_params, rest_params, body } => write!(f, "{:?}#[/{:?}/{:?}/{}/{:?}/{:?}/{}]", ids, 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 } => write!(f, "{:?}#[{:?}/{:?}/{:?}/{}/{:?}/{:?}/{}]", ids, lookup_name, de, id, wrap_level, sequence_params, rest_params, body),
MarkedForm::SuspendedPair{ hash, ids, attempted, car, cdr } => { MarkedForm::SuspendedPair{ hash, ids, attempted, car, cdr } => {
//write!(f, "{:?}{:?}#{{{}", ids, attempted, car)?; //write!(f, "{:?}{:?}#{{{}", ids, attempted, car)?;

View File

@@ -165,7 +165,7 @@ fn vapply_eval_test() { let g = grammar::TermParser::new(); let e = root_env();
))", *VAPPLY); ))", *VAPPLY);
// Won't work unless tail calls work // Won't work unless tail calls work
// so no PE? // so no PE?
eval_test(true, &g, &e, &format!("{} (badid 1000)", def_badid), 1000); eval_test(false, &g, &e, &format!("{} (badid 1000)", def_badid), 1000);
} }
static VMAP: Lazy<String> = Lazy::new(|| { static VMAP: Lazy<String> = Lazy::new(|| {
@@ -248,7 +248,7 @@ fn lapply_eval_test() { let g = grammar::TermParser::new(); let e = root_env();
))", *LAPPLY); ))", *LAPPLY);
// Won't work unless tail calls work // Won't work unless tail calls work
// takes a while though // takes a while though
eval_test(true, &g, &e, &format!("{} (lbadid 1000)", def_lbadid), 1000); eval_test(false, &g, &e, &format!("{} (lbadid 1000)", def_lbadid), 1000);
} }
static VFOLDL: Lazy<String> = Lazy::new(|| { static VFOLDL: Lazy<String> = Lazy::new(|| {
@@ -582,6 +582,6 @@ static RBTREE: Lazy<String> = Lazy::new(|| {
}); });
#[test] #[test]
fn rbtree_eval_test() { let g = grammar::TermParser::new(); let e = root_env(); fn rbtree_eval_test() { let g = grammar::TermParser::new(); let e = root_env();
eval_test(true, &g, &e, &format!("{} (reduce-test-tree (make-test-tree 10 map-empty))", *RBTREE), 1); eval_test(false, &g, &e, &format!("{} (reduce-test-tree (make-test-tree 10 map-empty))", *RBTREE), 1);
eval_test(true, &g, &e, &format!("{} (reduce-test-tree (make-test-tree 20 map-empty))", *RBTREE), 2); //eval_test(false, &g, &e, &format!("{} (reduce-test-tree (make-test-tree 20 map-empty))", *RBTREE), 2);
} }