From 8fa7acbdf11e50c5aa3da328b09b54f4c6dfa8e3 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Mon, 27 Mar 2023 01:27:25 -0400 Subject: [PATCH] Actually using the evaled param lookups with cons pairs etc - Tests failing - need to figure out how to really handle the *weird* case, and also the failing tests if the *wierd* case isn't the cause. Not sure if we need to track to prevent the dropping of the *not* redundant veval, or if the suspended symbol should hold onto the half-done env, or what --- kr/src/pe_ast.rs | 59 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/kr/src/pe_ast.rs b/kr/src/pe_ast.rs index 0821218..a340e1a 100644 --- a/kr/src/pe_ast.rs +++ b/kr/src/pe_ast.rs @@ -356,10 +356,11 @@ impl MarkedForm { }; Rc::new(MarkedForm::DeriComb{ lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body }) } - pub fn tag_name(self: &Rc, name: &str) -> Rc { + pub fn tag_name(self: &Rc, new_name: &str) -> Rc { match &**self { MarkedForm::DeriComb { lookup_name, ids, se, de, id, wrap_level, sequence_params, rest_params, body } => - Rc::new(MarkedForm::DeriComb { lookup_name: Some(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) }), + 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::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 }), _ => Rc::clone(self), } } @@ -415,6 +416,24 @@ impl MarkedForm { }; ids.heads.is_empty() && ids.tails.is_empty() } + pub fn is_pair(&self) -> bool { + match self { + MarkedForm::Pair(ids,car,cdr) => true, + _ => false, + } + } + pub fn is_suspended_param(&self) -> bool { + match self { + MarkedForm::SuspendedParamLookup { .. } => true, + _ => false, + } + } + pub fn is_suspended_env(&self) -> bool { + match self { + MarkedForm::SuspendedEnvLookup { .. } => true, + _ => false, + } + } pub fn unval(self: &Rc) -> Result> { match &**self { MarkedForm::Nil => Ok(Rc::clone(self)), @@ -479,28 +498,47 @@ impl MarkedForm { } } fn make_eval_prim(wrap_level: i32) -> Rc { - Rc::new(MarkedForm::PrimComb { name: "eval".to_owned(), nonval_ok: false, takes_de: false, wrap_level, f: eval_func }) + Rc::new(MarkedForm::PrimComb { name: "eval".to_owned(), nonval_ok: true, takes_de: false, wrap_level, f: eval_func }) } fn eval_func(bctx: BCtx, dctx: DCtx, p: Rc) -> Result<(BCtx,Rc)> { //println!("Ok, this is inside eval looking at {}", p); - if !p.car()?.is_value() { - Ok((bctx, MarkedForm::new_suspended_pair( Some(p.car().unwrap().ids()), make_eval_prim(0), p, None, None ))) + let x = p.car()?; + let e = p.cdr()?.car()?; + if !x.is_value() { + println!("Checking compatability"); + if let (MarkedForm::SuspendedParamLookup { name, id, cdr_num, car, evaled: false }, MarkedForm::SuspendedEnvLookup { name: oname, id: oid }) = (&*x, &*e) { + if id == oid { + 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 ))) } else { //println!("Ok, returning new suspended env eval with"); //println!("\t{} {}", p.car()?.unval()?, p.cdr()?.car()?); - Ok((bctx, MarkedForm::new_suspended_env_eval(p.car()?.unval()?, p.cdr()?.car()?))) + Ok((bctx, MarkedForm::new_suspended_env_eval(x.unval()?, e))) } } // Implement the suspended param / suspended env traversal fn make_cons_prim(wrap_level: i32) -> Rc { - Rc::new(MarkedForm::PrimComb { name: "cons".to_owned(), nonval_ok: false, takes_de: false, wrap_level, f: cons_func}) + Rc::new(MarkedForm::PrimComb { name: "cons".to_owned(), nonval_ok: true, takes_de: false, wrap_level, f: cons_func}) } fn cons_func(bctx: BCtx, dctx: DCtx, p: Rc) -> Result<(BCtx,Rc)> { + // the non-vals we should allow are + // (value . SuspendedParam) + // ! maybe not!(value . SuspendedEnv) + // (value . pair) + // (pair . pair) let h = p.car()?; let t = p.cdr()?.car()?; - Ok((bctx, MarkedForm::new_pair(h, t))) + if !(h.is_value() || h.is_pair()) { + Ok((bctx, MarkedForm::new_suspended_pair(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))) + } else { + Ok((bctx, MarkedForm::new_pair(h, t))) + } } fn make_car_prim(wrap_level: i32)-> Rc { Rc::new(MarkedForm::PrimComb { name: "car".to_owned(), nonval_ok: true, takes_de: false, wrap_level, f: car_func}) @@ -726,7 +764,8 @@ pub fn partial_eval(bctx_in: BCtx, dctx_in: DCtx, form: Rc) -> Resul // - this current env ends in a suspended param/env, and that id is in ids (the *weird* case) if let MarkedForm::SuspendedEnvEval { x, e, .. } = &*new_form { if !x.ids().may_contain_id(&true_id) { - println!("{:ident$}Dropping redundent eval: {}", "", x, 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); next_form = Some(Rc::clone(x)); // do we still need force for drop redundent veval? // Not while it's not recursive, at elaset @@ -796,6 +835,7 @@ fn partial_eval_step(x: &Rc, bctx: BCtx, dctx: &mut DCtx) -> Result< 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 { + println!("\tgot for symbol {} {}", name, t.car()?.cdr()?.tag_name(name)); return Ok((bctx, t.car()?.cdr()?.tag_name(name))); } else { t = t.cdr()?; @@ -815,6 +855,7 @@ fn partial_eval_step(x: &Rc, bctx: BCtx, dctx: &mut DCtx) -> Result< } } } + println!("\tcouldn't find it, returning suspended"); return Ok((bctx, Rc::new(MarkedForm::SuspendedSymbol(t.ids(), name.clone())))); }, MarkedForm::SuspendedEnvLookup { name, id } => {