From 049624a840a97209940d36cc3cf69aa44929488b Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Wed, 22 Mar 2023 01:06:24 -0400 Subject: [PATCH] Baby steps towards handling non-val car/cdr (eventually cons) --- kr/src/pe_ast.rs | 39 ++++++++++++++++++++++++--------------- kr/src/test.rs | 2 ++ 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/kr/src/pe_ast.rs b/kr/src/pe_ast.rs index 87eacc4..8711e0d 100644 --- a/kr/src/pe_ast.rs +++ b/kr/src/pe_ast.rs @@ -456,13 +456,13 @@ impl MarkedForm { } } } -fn make_eval_prim() -> Rc { - Rc::new(MarkedForm::PrimComb { name: "eval".to_owned(), nonval_ok: false, takes_de: false, wrap_level: 1, f: eval_func }) +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 }) } 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(), p, None, None ))) + Ok((bctx, MarkedForm::new_suspended_pair( Some(p.car().unwrap().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()?); @@ -472,25 +472,33 @@ fn eval_func(bctx: BCtx, dctx: DCtx, p: Rc) -> Result<(BCtx,Rc Rc { - Rc::new(MarkedForm::PrimComb { name: "cons".to_owned(), nonval_ok: false, takes_de: false, wrap_level: 1, f: cons_func}) +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}) } fn cons_func(bctx: BCtx, dctx: DCtx, p: Rc) -> Result<(BCtx,Rc)> { let h = p.car()?; let t = p.cdr()?.car()?; Ok((bctx, MarkedForm::new_pair(h, t))) } -fn make_car_prim()-> Rc { - Rc::new(MarkedForm::PrimComb { name: "car".to_owned(), nonval_ok: false, takes_de: false, wrap_level: 1, f: car_func}) +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}) } fn car_func(bctx: BCtx, dctx: DCtx, p: Rc) -> Result<(BCtx,Rc)> { - Ok((bctx, p.car()?.car()?)) + 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))), + } } -fn make_cdr_prim() -> Rc { - Rc::new(MarkedForm::PrimComb { name: "cdr".to_owned(), nonval_ok: false, takes_de: false, wrap_level: 1, f: cdr_func}) +fn make_cdr_prim(wrap_level: i32) -> Rc { + Rc::new(MarkedForm::PrimComb { name: "cdr".to_owned(), nonval_ok: true, takes_de: false, wrap_level, f: cdr_func}) } fn cdr_func(bctx: BCtx, dctx: DCtx, p: Rc) -> Result<(BCtx,Rc)> { - Ok((bctx, p.car()?.cdr()?)) + 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))), + } } @@ -531,10 +539,10 @@ pub fn mark(form: Rc
, bctx: BCtx) -> (BCtx, Rc) { 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 ))) }}), - "eval" => make_eval_prim(), - "cons" => make_cons_prim(), - "car" => make_car_prim(), - "cdr" => make_cdr_prim(), + "eval" => make_eval_prim(1), + "cons" => make_cons_prim(1), + "car" => make_car_prim(1), + "cdr" => make_cdr_prim(1), "debug" => make_debug_prim(), // Like Debug, listed as wrap_level 1 so bothe sides are pe'd, even though it would // be sequencing at runtime @@ -761,6 +769,7 @@ fn partial_eval_step(x: &Rc, bctx: BCtx, dctx: &mut DCtx) -> Result< MarkedForm::SuspendedSymbol(ids, 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); loop { if let Ok(cmp) = t.car().and_then(|kv| kv.car()).and_then(|s| s.sym().map(|s| s.to_owned())) { diff --git a/kr/src/test.rs b/kr/src/test.rs index cc4473b..0baf9fa 100644 --- a/kr/src/test.rs +++ b/kr/src/test.rs @@ -51,6 +51,8 @@ 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 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: {} }#{ Some(\"p\")(EnvID(1)0true) Some(\"de\")(EnvID(1)env)} NeededIds { heads: {EnvID(1)}, tails: {}, body_stopped: {}, if_stopped: {} }#{ Some(\"p\")(EnvID(1)1true) Some(\"de\")(EnvID(1)env)}}]"); } #[test]