From 6edbe7d2c8a97811eadc612bbeeb358fe0da799d Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Sun, 9 Jul 2023 00:24:50 -0400 Subject: [PATCH] Continue moving stuff around to simplify before opt, and then start sketching out wrapped values and trace - just realized we might need all values to be wrapped tohande side effects that don't depend on input but still have effects (mutation, now ugh and assert) --- kv/src/basic.rs | 99 ++++++++++++++------------- kv/src/eval.rs | 21 +++--- kv/src/opt.rs | 177 ++++++++++++++++++++++++++++-------------------- 3 files changed, 161 insertions(+), 136 deletions(-) diff --git a/kv/src/basic.rs b/kv/src/basic.rs index 0f6bf18..1da2885 100644 --- a/kv/src/basic.rs +++ b/kv/src/basic.rs @@ -67,7 +67,7 @@ impl fmt::Display for Form { } } -impl FormT for Form { +impl Form { fn nil() -> Rc { Rc::new(Form::Nil) } @@ -84,6 +84,16 @@ impl FormT for Form { _ => None, } } + pub fn append(&self, x: Rc
) -> Option> { + match self { + Form::Pair(car, cdr) => cdr.append(x).map(|x| Rc::new(Form::Pair(Rc::clone(car), x))), + Form::Nil => Some(Rc::new(Form::Pair(x, Rc::new(Form::Nil)))), + _ => None, + } + } +} + +impl FormT for Form { fn sym(&self) -> Option<&str> { match self { Form::Symbol(s) => Some(s), @@ -114,13 +124,6 @@ impl FormT for Form { _ => false, } } - fn append(&self, x: Rc) -> Option> { - match self { - Form::Pair(car, cdr) => cdr.append(x).map(|x| Rc::new(Form::Pair(Rc::clone(car), x))), - Form::Nil => Some(Rc::new(Form::Pair(x, Rc::new(Form::Nil)))), - _ => None, - } - } fn call(&self, p: Rc, e: Rc, nc: Box>, metac: Cont) -> Cursor { match self { Form::PrimComb{eval_limit, ins} => { @@ -142,96 +145,96 @@ impl FormT for Form { } } } - fn impl_prim(ins: PrimCombI, e: Rc, ps: Rc, c: Cont, metac: Cont) -> Cursor { + fn impl_prim(ins: PrimCombI, e: Rc, ps: Vec>, c: Cont, metac: Cont) -> Cursor { match ins { - PrimCombI::Eval => Cursor { f: ps.car().unwrap(), c: Cont::Eval { e: ps.cdr().unwrap().car().unwrap(), nc: Box::new(c) }, metac }, + PrimCombI::Eval => Cursor { f: Rc::clone(&ps[0]), c: Cont::Eval { e: Rc::clone(&ps[1]), nc: Box::new(c) }, metac }, PrimCombI::Vau => { - let de = ps.car().unwrap().sym().map(|s| s.to_owned()); - let params = ps.cdr().unwrap().car().unwrap().sym().unwrap().to_owned(); - let body = ps.cdr().unwrap().cdr().unwrap().car().unwrap(); + let de = ps[0].sym().map(|s| s.to_owned()); + let params = ps[1].sym().unwrap().to_owned(); + let body = Rc::clone(&ps[2]); Cursor { f: Rc::new(Form::DeriComb { se: e, de, params, body }), c, metac } }, - PrimCombI::If => if ps.car().unwrap().truthy() { - Cursor { f: ps.cdr().unwrap().car().unwrap(), c: Cont::Eval { e: e, nc: Box::new(c) }, metac } + PrimCombI::If => if ps[0].truthy() { + Cursor { f: Rc::clone(&ps[1]), c: Cont::Eval { e: e, nc: Box::new(c) }, metac } } else { - Cursor { f: ps.cdr().unwrap().cdr().unwrap().car().unwrap(), c: Cont::Eval { e: e, nc: Box::new(c) }, metac } + Cursor { f: Rc::clone(&ps[2]), c: Cont::Eval { e: e, nc: Box::new(c) }, metac } }, - PrimCombI::Reset => Cursor { f: ps.car().unwrap(), + PrimCombI::Reset => Cursor { f: Rc::clone(&ps[0]), c: Cont::Eval { e: e, nc: Box::new(Cont::MetaRet) }, metac: Cont::CatchRet { nc: Box::new(c), restore_meta: Box::new(metac) } }, - PrimCombI::Shift => Cursor { f: ps.car().unwrap(), + PrimCombI::Shift => Cursor { f: Rc::clone(&ps[0]), c: Cont::Call { p: Rc::new(Form::Pair(Rc::new(Form::ContComb(c)), Rc::new(Form::Nil))), e: e, nc: Box::new(Cont::MetaRet) }, metac: Cont::CatchRet { nc: Box::new(metac.clone()), restore_meta: Box::new(metac) } }, PrimCombI::Assert => { - let thing = ps.car().unwrap(); + let thing = Rc::clone(&ps[0]); if !thing.truthy() { println!("Assert failed: {:?}", thing); } assert!(thing.truthy()); - Cursor { f: ps.cdr().unwrap().car().unwrap(), c: Cont::Eval { e: e, nc: Box::new(c) }, metac } + Cursor { f: Rc::clone(&ps[1]), c: Cont::Eval { e: e, nc: Box::new(c) }, metac } }, - PrimCombI::Cell => Cursor { f: Rc::new(Form::Cell(RefCell::new(ps.car().unwrap()))), c, metac }, - PrimCombI::Set => match &*ps.car().unwrap() { - Form::Cell(cell) => Cursor { f: cell.replace(ps.cdr().unwrap().car().unwrap()), c, metac }, + PrimCombI::Cell => Cursor { f: Rc::new(Form::Cell(RefCell::new(Rc::clone(&ps[0])))), c, metac }, + PrimCombI::Set => match &*ps[0] { + Form::Cell(cell) => Cursor { f: cell.replace(Rc::clone(&ps[1])), c, metac }, _ => panic!("set on not cell"), }, - PrimCombI::Get => match &*ps.car().unwrap() { + PrimCombI::Get => match &*ps[0] { Form::Cell(cell) => Cursor { f: Rc::clone(&cell.borrow()), c, metac }, _ => panic!("get on not cell"), }, - PrimCombI::Cons => Cursor { f: Rc::new(Form::Pair(ps.car().unwrap(), ps.cdr().unwrap().car().unwrap())), c, metac }, - PrimCombI::Car => Cursor { f: ps.car().unwrap().car().unwrap(), c, metac }, - PrimCombI::Cdr => Cursor { f: ps.car().unwrap().cdr().unwrap(), c, metac }, - PrimCombI::Quote => Cursor { f: ps.car().unwrap(), c, metac }, + PrimCombI::Cons => Cursor { f: Rc::new(Form::Pair(Rc::clone(&ps[0]), Rc::clone(&ps[1]))), c, metac }, + PrimCombI::Car => Cursor { f: ps[0].car().unwrap(), c, metac }, + PrimCombI::Cdr => Cursor { f: ps[0].cdr().unwrap(), c, metac }, + PrimCombI::Quote => Cursor { f: Rc::clone(&ps[0]), c, metac }, - PrimCombI::Eq => Cursor { f: Rc::new(Form::Bool(ps.car().unwrap() == ps.cdr().unwrap().car().unwrap())), c, metac }, - PrimCombI::Lt => Cursor { f: Rc::new(Form::Bool(ps.car().unwrap().int().unwrap() < ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::LEq => Cursor { f: Rc::new(Form::Bool(ps.car().unwrap().int().unwrap() <= ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::Gt => Cursor { f: Rc::new(Form::Bool(ps.car().unwrap().int().unwrap() > ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::GEq => Cursor { f: Rc::new(Form::Bool(ps.car().unwrap().int().unwrap() >= ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, + PrimCombI::Eq => Cursor { f: Rc::new(Form::Bool(ps[0] == ps[1])), c, metac }, + PrimCombI::Lt => Cursor { f: Rc::new(Form::Bool(ps[0].int().unwrap() < ps[1].int().unwrap())), c, metac }, + PrimCombI::LEq => Cursor { f: Rc::new(Form::Bool(ps[0].int().unwrap() <= ps[1].int().unwrap())), c, metac }, + PrimCombI::Gt => Cursor { f: Rc::new(Form::Bool(ps[0].int().unwrap() > ps[1].int().unwrap())), c, metac }, + PrimCombI::GEq => Cursor { f: Rc::new(Form::Bool(ps[0].int().unwrap() >= ps[1].int().unwrap())), c, metac }, - PrimCombI::Plus => Cursor { f: Rc::new(Form::Int(ps.car().unwrap().int().unwrap() + ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::Minus => Cursor { f: Rc::new(Form::Int(ps.car().unwrap().int().unwrap() - ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::Mult => Cursor { f: Rc::new(Form::Int(ps.car().unwrap().int().unwrap() * ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::Div => Cursor { f: Rc::new(Form::Int(ps.car().unwrap().int().unwrap() / ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::Mod => Cursor { f: Rc::new(Form::Int(ps.car().unwrap().int().unwrap() % ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::And => Cursor { f: Rc::new(Form::Int(ps.car().unwrap().int().unwrap() & ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::Or => Cursor { f: Rc::new(Form::Int(ps.car().unwrap().int().unwrap() | ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::Xor => Cursor { f: Rc::new(Form::Int(ps.car().unwrap().int().unwrap() ^ ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, + PrimCombI::Plus => Cursor { f: Rc::new(Form::Int(ps[0].int().unwrap() + ps[1].int().unwrap())), c, metac }, + PrimCombI::Minus => Cursor { f: Rc::new(Form::Int(ps[0].int().unwrap() - ps[1].int().unwrap())), c, metac }, + PrimCombI::Mult => Cursor { f: Rc::new(Form::Int(ps[0].int().unwrap() * ps[1].int().unwrap())), c, metac }, + PrimCombI::Div => Cursor { f: Rc::new(Form::Int(ps[0].int().unwrap() / ps[1].int().unwrap())), c, metac }, + PrimCombI::Mod => Cursor { f: Rc::new(Form::Int(ps[0].int().unwrap() % ps[1].int().unwrap())), c, metac }, + PrimCombI::And => Cursor { f: Rc::new(Form::Int(ps[0].int().unwrap() & ps[1].int().unwrap())), c, metac }, + PrimCombI::Or => Cursor { f: Rc::new(Form::Int(ps[0].int().unwrap() | ps[1].int().unwrap())), c, metac }, + PrimCombI::Xor => Cursor { f: Rc::new(Form::Int(ps[0].int().unwrap() ^ ps[1].int().unwrap())), c, metac }, - PrimCombI::CombP => Cursor { f: Rc::new(Form::Bool(match &*ps.car().unwrap() { + PrimCombI::CombP => Cursor { f: Rc::new(Form::Bool(match &*ps[0] { Form::PrimComb { .. } => true, Form::DeriComb { .. } => true, _ => false, })), c, metac }, - PrimCombI::CellP => Cursor { f: Rc::new(Form::Bool(match &*ps.car().unwrap() { + PrimCombI::CellP => Cursor { f: Rc::new(Form::Bool(match &*ps[0] { Form::Cell(_c) => true, _ => false, })), c, metac }, - PrimCombI::PairP => Cursor { f: Rc::new(Form::Bool(match &*ps.car().unwrap() { + PrimCombI::PairP => Cursor { f: Rc::new(Form::Bool(match &*ps[0] { Form::Pair(_a,_b) => true, _ => false, })), c, metac }, - PrimCombI::SymbolP => Cursor { f: Rc::new(Form::Bool(match &*ps.car().unwrap() { + PrimCombI::SymbolP => Cursor { f: Rc::new(Form::Bool(match &*ps[0] { Form::Symbol(_) => true, _ => false, })), c, metac }, - PrimCombI::IntP => Cursor { f: Rc::new(Form::Bool(match &*ps.car().unwrap() { + PrimCombI::IntP => Cursor { f: Rc::new(Form::Bool(match &*ps[0] { Form::Int(_) => true, _ => false, })), c, metac }, - PrimCombI::BoolP => Cursor { f: Rc::new(Form::Bool(match &*ps.car().unwrap() { + PrimCombI::BoolP => Cursor { f: Rc::new(Form::Bool(match &*ps[0] { Form::Bool(_) => true, _ => false, })), c, metac }, - PrimCombI::NilP => Cursor { f: Rc::new(Form::Bool(ps.car().unwrap().is_nil())), c, metac }, + PrimCombI::NilP => Cursor { f: Rc::new(Form::Bool(ps[0].is_nil())), c, metac }, } } } diff --git a/kv/src/eval.rs b/kv/src/eval.rs index b7f71b1..863df23 100644 --- a/kv/src/eval.rs +++ b/kv/src/eval.rs @@ -5,17 +5,13 @@ use std::cell::RefCell; use std::convert::From; pub trait FormT: std::fmt::Debug { - fn nil() -> Rc; - fn truthy(&self) -> bool; - fn int(&self) -> Option; fn sym(&self) -> Option<&str>; fn pair(&self) -> Option<(Rc,Rc)>; fn car(&self) -> Option>; fn cdr(&self) -> Option>; - fn call(&self, p: Rc, e: Rc, nc: Box>, metac: Cont) -> Cursor; fn is_nil(&self) -> bool; - fn append(&self, x: Rc) -> Option>; - fn impl_prim(ins: PrimCombI, e: Rc, ps: Rc, c: Cont, metac: Cont) -> Cursor; + fn call(&self, p: Rc, e: Rc, nc: Box>, metac: Cont) -> Cursor; + fn impl_prim(ins: PrimCombI, e: Rc, ps: Vec>, c: Cont, metac: Cont) -> Cursor; } #[derive(Debug, Eq, PartialEq)] @@ -25,7 +21,7 @@ pub enum Cont { CatchRet { nc: Box>, restore_meta: Box> }, Eval { e: Rc, nc: Box> }, Call { p: Rc, e: Rc, nc: Box> }, - PramEval { eval_limit: i32, to_eval: Rc, collected: Option>, e: Rc, ins: PrimCombI, nc: Box> }, + PramEval { eval_limit: i32, to_eval: Rc, collected: Option>>, e: Rc, ins: PrimCombI, nc: Box> }, } impl Clone for Cont { fn clone(&self) -> Self { @@ -36,7 +32,7 @@ impl Clone for Cont { Cont::Eval { e, nc } => Cont::Eval { e: Rc::clone(e), nc: nc.clone() }, Cont::Call { p, e, nc } => Cont::Call { p: Rc::clone(p), e: Rc::clone(e), nc: nc.clone() }, Cont::PramEval { eval_limit, to_eval, collected, e, ins, nc} => Cont::PramEval { eval_limit: *eval_limit, to_eval: Rc::clone(to_eval), - collected: collected.as_ref().map(|x| Rc::clone(x)), + collected: collected.as_ref().map(|x| x.iter().map(|x| Rc::clone(x)).collect()), e: Rc::clone(e), ins: ins.clone(), nc: nc.clone() }, } } @@ -71,14 +67,13 @@ pub fn eval(e: Rc, f: Rc) -> Rc { } }, Cont::PramEval { eval_limit, to_eval, collected, e, ins, nc } => { - let next_collected = if let Some(collected) = collected { - collected.append(f).unwrap() - } else { F::nil() }; + let mut next_collected = if let Some(mut collected) = collected { + collected.push(f); collected + } else { vec![] }; if eval_limit == 0 || to_eval.is_nil() { let mut traverse = to_eval; - let mut next_collected = next_collected; while !traverse.is_nil() { - next_collected = next_collected.append(traverse.car().unwrap()).unwrap(); + next_collected.push(traverse.car().unwrap()); traverse = traverse.cdr().unwrap(); } cursor = F::impl_prim(ins, e, next_collected, *nc, metac); diff --git a/kv/src/opt.rs b/kv/src/opt.rs index 32b4e54..0107f19 100644 --- a/kv/src/opt.rs +++ b/kv/src/opt.rs @@ -16,8 +16,16 @@ pub enum OptForm { Cell(RefCell>), Pair(Rc,Rc), PrimComb { eval_limit: i32, ins: PrimCombI }, - DeriComb { se: Rc, de: Option, params: String, body: Rc }, + DeriComb { se: Rc, de: Option, params: String, body: Rc, code: Option>>> }, ContComb(Cont), + + // Hmm this needs to wrap both outside and inside, as inside can still emit code... + // or do we need to wrap everything b/c side effects (mutation and assert, at least)... + CodeForm { code_offset: usize, code: Rc>>, inner_value: Rc }, +} +#[derive(Debug, Eq, PartialEq)] +pub enum ByteCode { + Ins(PrimCombI) } impl fmt::Display for OptForm { @@ -49,10 +57,11 @@ impl fmt::Display for OptForm { } }, OptForm::PrimComb { eval_limit, ins } => write!(f, "<{eval_limit}> - {ins:?}"), - OptForm::DeriComb { se: _, de, params, body } => { + OptForm::DeriComb { se: _, de, params, body, code: _ } => { write!(f, "<{} {} {}>", de.as_ref().unwrap_or(&"".to_string()), params, body) }, OptForm::ContComb(_) => write!(f, ""), + OptForm::CodeForm { code_offset, inner_value, .. } => write!(f, "~code{code_offset}~({inner_value})"), } } } @@ -74,6 +83,32 @@ impl From<&Form> for Rc { } impl OptForm { + fn nil() -> Rc { + Rc::new(OptForm::Nil) + } + fn truthy(&self) -> bool { + match self { + OptForm::Bool(b) => *b, + OptForm::Nil => false, + OptForm::CodeForm { inner_value, .. } => inner_value.truthy(), + _ => true, + } + } + fn int(&self) -> Option { + match self { + OptForm::Int(i) => Some(*i), + OptForm::CodeForm { inner_value, .. } => inner_value.int(), + _ => None, + } + } + fn append(&self, x: Rc) -> Option> { + match self { + OptForm::Pair(car, cdr) => cdr.append(x).map(|x| Rc::new(OptForm::Pair(Rc::clone(car), x))), + OptForm::Nil => Some(Rc::new(OptForm::Pair(x, Rc::new(OptForm::Nil)))), + OptForm::CodeForm { inner_value, .. } => inner_value.append(x), + _ => None, + } + } pub fn congruent(&self, other: &Form) -> bool { match other { Form::Nil => *self == OptForm::Nil, @@ -90,65 +125,47 @@ impl OptForm { } impl FormT for OptForm { - fn nil() -> Rc { - Rc::new(OptForm::Nil) - } - fn truthy(&self) -> bool { - match self { - OptForm::Bool(b) => *b, - OptForm::Nil => false, - _ => true, - } - } - fn int(&self) -> Option { - match self { - OptForm::Int(i) => Some(*i), - _ => None, - } - } fn sym(&self) -> Option<&str> { match self { OptForm::Symbol(s) => Some(s), + OptForm::CodeForm { inner_value, .. } => inner_value.sym(), _ => None, } } fn pair(&self) -> Option<(Rc,Rc)> { match self { OptForm::Pair(car, cdr) => Some((Rc::clone(car),Rc::clone(cdr))), + OptForm::CodeForm { inner_value, .. } => inner_value.pair(), _ => None, } } fn car(&self) -> Option> { match self { OptForm::Pair(car, _cdr) => Some(Rc::clone(car)), + OptForm::CodeForm { inner_value, .. } => inner_value.car(), _ => None, } } fn cdr(&self) -> Option> { match self { OptForm::Pair(_car, cdr) => Some(Rc::clone(cdr)), + OptForm::CodeForm { inner_value, .. } => inner_value.cdr(), _ => None, } } fn is_nil(&self) -> bool { match self { OptForm::Nil => true, + OptForm::CodeForm { inner_value, .. } => inner_value.is_nil(), _ => false, } } - fn append(&self, x: Rc) -> Option> { - match self { - OptForm::Pair(car, cdr) => cdr.append(x).map(|x| Rc::new(OptForm::Pair(Rc::clone(car), x))), - OptForm::Nil => Some(Rc::new(OptForm::Pair(x, Rc::new(OptForm::Nil)))), - _ => None, - } - } fn call(&self, p: Rc, e: Rc, nc: Box>, metac: Cont) -> Cursor { match self { OptForm::PrimComb{eval_limit, ins} => { Cursor { f: Self::nil(), c: Cont::PramEval { eval_limit: *eval_limit, to_eval: p, collected: None, e, ins: *ins, nc: nc }, metac } } - OptForm::DeriComb {se, de, params, body} => { + OptForm::DeriComb {se, de, params, body, code} => { let mut new_e = Rc::clone(se); if let Some(de) = de { new_e = assoc(&de, Rc::clone(&e), new_e); @@ -159,101 +176,111 @@ impl FormT for OptForm { OptForm::ContComb(c) => { Cursor { f: p.car().unwrap(), c: Cont::Eval { e, nc: Box::new(c.clone()) }, metac: Cont::CatchRet { nc: nc, restore_meta: Box::new(metac) } } } + OptForm::CodeForm { inner_value, .. } => { + inner_value.call(p, e, nc, metac) + } _ => { panic!("Tried to call not a Prim/DeriComb/ContComb {:?}, nc was {:?}", self, nc); } } } - fn impl_prim(ins: PrimCombI, e: Rc, ps: Rc, c: Cont, metac: Cont) -> Cursor { + fn impl_prim(ins: PrimCombI, e: Rc, ps: Vec>, c: Cont, metac: Cont) -> Cursor { match ins { - PrimCombI::Eval => Cursor { f: ps.car().unwrap(), c: Cont::Eval { e: ps.cdr().unwrap().car().unwrap(), nc: Box::new(c) }, metac }, + PrimCombI::Eval => Cursor { f: Rc::clone(&ps[0]), c: Cont::Eval { e: Rc::clone(&ps[1]), nc: Box::new(c) }, metac }, PrimCombI::Vau => { - let de = ps.car().unwrap().sym().map(|s| s.to_owned()); - let params = ps.cdr().unwrap().car().unwrap().sym().unwrap().to_owned(); - let body = ps.cdr().unwrap().cdr().unwrap().car().unwrap(); - - Cursor { f: Rc::new(OptForm::DeriComb { se: e, de, params, body }), c, metac } + let de = ps[0].sym().map(|s| s.to_owned()); + let params = ps[1].sym().unwrap().to_owned(); + let body = Rc::clone(&ps[2]); + Cursor { f: Rc::new(OptForm::DeriComb { se: e, de, params, body, code: Some(Rc::new(RefCell::new(vec![]))) }), c, metac } }, - PrimCombI::If => if ps.car().unwrap().truthy() { - Cursor { f: ps.cdr().unwrap().car().unwrap(), c: Cont::Eval { e: e, nc: Box::new(c) }, metac } + PrimCombI::If => if ps[0].truthy() { + Cursor { f: Rc::clone(&ps[1]), c: Cont::Eval { e: e, nc: Box::new(c) }, metac } } else { - Cursor { f: ps.cdr().unwrap().cdr().unwrap().car().unwrap(), c: Cont::Eval { e: e, nc: Box::new(c) }, metac } + Cursor { f: Rc::clone(&ps[2]), c: Cont::Eval { e: e, nc: Box::new(c) }, metac } }, - PrimCombI::Reset => Cursor { f: ps.car().unwrap(), + PrimCombI::Reset => Cursor { f: Rc::clone(&ps[0]), c: Cont::Eval { e: e, nc: Box::new(Cont::MetaRet) }, metac: Cont::CatchRet { nc: Box::new(c), restore_meta: Box::new(metac) } }, - PrimCombI::Shift => Cursor { f: ps.car().unwrap(), + PrimCombI::Shift => Cursor { f: Rc::clone(&ps[0]), c: Cont::Call { p: Rc::new(OptForm::Pair(Rc::new(OptForm::ContComb(c)), Rc::new(OptForm::Nil))), e: e, nc: Box::new(Cont::MetaRet) }, metac: Cont::CatchRet { nc: Box::new(metac.clone()), restore_meta: Box::new(metac) } }, PrimCombI::Assert => { - let thing = ps.car().unwrap(); + let thing = Rc::clone(&ps[0]); if !thing.truthy() { println!("Assert failed: {:?}", thing); } assert!(thing.truthy()); - Cursor { f: ps.cdr().unwrap().car().unwrap(), c: Cont::Eval { e: e, nc: Box::new(c) }, metac } + Cursor { f: Rc::clone(&ps[1]), c: Cont::Eval { e: e, nc: Box::new(c) }, metac } }, - PrimCombI::Cell => Cursor { f: Rc::new(OptForm::Cell(RefCell::new(ps.car().unwrap()))), c, metac }, - PrimCombI::Set => match &*ps.car().unwrap() { - OptForm::Cell(cell) => Cursor { f: cell.replace(ps.cdr().unwrap().car().unwrap()), c, metac }, + PrimCombI::Cell => Cursor { f: Rc::new(OptForm::Cell(RefCell::new(Rc::clone(&ps[0])))), c, metac }, + PrimCombI::Set => match &*ps[0] { + // TODO OptForm::CodeForm { inner_value, .. } => inner_value.is_nil(), + OptForm::Cell(cell) => Cursor { f: cell.replace(Rc::clone(&ps[1])), c, metac }, _ => panic!("set on not cell"), }, - PrimCombI::Get => match &*ps.car().unwrap() { + PrimCombI::Get => match &*ps[0] { + // TODO OptForm::CodeForm { inner_value, .. } => inner_value.is_nil(), OptForm::Cell(cell) => Cursor { f: Rc::clone(&cell.borrow()), c, metac }, _ => panic!("get on not cell"), }, - PrimCombI::Cons => Cursor { f: Rc::new(OptForm::Pair(ps.car().unwrap(), ps.cdr().unwrap().car().unwrap())), c, metac }, - PrimCombI::Car => Cursor { f: ps.car().unwrap().car().unwrap(), c, metac }, - PrimCombI::Cdr => Cursor { f: ps.car().unwrap().cdr().unwrap(), c, metac }, - PrimCombI::Quote => Cursor { f: ps.car().unwrap(), c, metac }, + PrimCombI::Cons => Cursor { f: Rc::new(OptForm::Pair(Rc::clone(&ps[0]), Rc::clone(&ps[1]))), c, metac }, + PrimCombI::Car => Cursor { f: ps[0].car().unwrap(), c, metac }, + PrimCombI::Cdr => Cursor { f: ps[0].cdr().unwrap(), c, metac }, + PrimCombI::Quote => Cursor { f: Rc::clone(&ps[0]), c, metac }, - PrimCombI::Eq => Cursor { f: Rc::new(OptForm::Bool(ps.car().unwrap() == ps.cdr().unwrap().car().unwrap())), c, metac }, - PrimCombI::Lt => Cursor { f: Rc::new(OptForm::Bool(ps.car().unwrap().int().unwrap() < ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::LEq => Cursor { f: Rc::new(OptForm::Bool(ps.car().unwrap().int().unwrap() <= ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::Gt => Cursor { f: Rc::new(OptForm::Bool(ps.car().unwrap().int().unwrap() > ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::GEq => Cursor { f: Rc::new(OptForm::Bool(ps.car().unwrap().int().unwrap() >= ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, + PrimCombI::Eq => Cursor { f: Rc::new(OptForm::Bool(ps[0] == ps[1])), c, metac }, + PrimCombI::Lt => Cursor { f: Rc::new(OptForm::Bool(ps[0].int().unwrap() < ps[1].int().unwrap())), c, metac }, + PrimCombI::LEq => Cursor { f: Rc::new(OptForm::Bool(ps[0].int().unwrap() <= ps[1].int().unwrap())), c, metac }, + PrimCombI::Gt => Cursor { f: Rc::new(OptForm::Bool(ps[0].int().unwrap() > ps[1].int().unwrap())), c, metac }, + PrimCombI::GEq => Cursor { f: Rc::new(OptForm::Bool(ps[0].int().unwrap() >= ps[1].int().unwrap())), c, metac }, - PrimCombI::Plus => Cursor { f: Rc::new(OptForm::Int(ps.car().unwrap().int().unwrap() + ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::Minus => Cursor { f: Rc::new(OptForm::Int(ps.car().unwrap().int().unwrap() - ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::Mult => Cursor { f: Rc::new(OptForm::Int(ps.car().unwrap().int().unwrap() * ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::Div => Cursor { f: Rc::new(OptForm::Int(ps.car().unwrap().int().unwrap() / ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::Mod => Cursor { f: Rc::new(OptForm::Int(ps.car().unwrap().int().unwrap() % ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::And => Cursor { f: Rc::new(OptForm::Int(ps.car().unwrap().int().unwrap() & ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::Or => Cursor { f: Rc::new(OptForm::Int(ps.car().unwrap().int().unwrap() | ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, - PrimCombI::Xor => Cursor { f: Rc::new(OptForm::Int(ps.car().unwrap().int().unwrap() ^ ps.cdr().unwrap().car().unwrap().int().unwrap())), c, metac }, + PrimCombI::Plus => Cursor { f: Rc::new(OptForm::Int(ps[0].int().unwrap() + ps[1].int().unwrap())), c, metac }, + PrimCombI::Minus => Cursor { f: Rc::new(OptForm::Int(ps[0].int().unwrap() - ps[1].int().unwrap())), c, metac }, + PrimCombI::Mult => Cursor { f: Rc::new(OptForm::Int(ps[0].int().unwrap() * ps[1].int().unwrap())), c, metac }, + PrimCombI::Div => Cursor { f: Rc::new(OptForm::Int(ps[0].int().unwrap() / ps[1].int().unwrap())), c, metac }, + PrimCombI::Mod => Cursor { f: Rc::new(OptForm::Int(ps[0].int().unwrap() % ps[1].int().unwrap())), c, metac }, + PrimCombI::And => Cursor { f: Rc::new(OptForm::Int(ps[0].int().unwrap() & ps[1].int().unwrap())), c, metac }, + PrimCombI::Or => Cursor { f: Rc::new(OptForm::Int(ps[0].int().unwrap() | ps[1].int().unwrap())), c, metac }, + PrimCombI::Xor => Cursor { f: Rc::new(OptForm::Int(ps[0].int().unwrap() ^ ps[1].int().unwrap())), c, metac }, - PrimCombI::CombP => Cursor { f: Rc::new(OptForm::Bool(match &*ps.car().unwrap() { + PrimCombI::CombP => Cursor { f: Rc::new(OptForm::Bool(match &*ps[0] { + // TODO OptForm::CodeForm { inner_value, .. } => inner_value.is_nil(), OptForm::PrimComb { .. } => true, OptForm::DeriComb { .. } => true, - _ => false, + _ => false, })), c, metac }, - PrimCombI::CellP => Cursor { f: Rc::new(OptForm::Bool(match &*ps.car().unwrap() { + PrimCombI::CellP => Cursor { f: Rc::new(OptForm::Bool(match &*ps[0] { + // TODO OptForm::CodeForm { inner_value, .. } => inner_value.is_nil(), OptForm::Cell(_c) => true, - _ => false, - })), c, metac }, - PrimCombI::PairP => Cursor { f: Rc::new(OptForm::Bool(match &*ps.car().unwrap() { - OptForm::Pair(_a,_b) => true, _ => false, })), c, metac }, - PrimCombI::SymbolP => Cursor { f: Rc::new(OptForm::Bool(match &*ps.car().unwrap() { + PrimCombI::PairP => Cursor { f: Rc::new(OptForm::Bool(match &*ps[0] { + // TODO OptForm::CodeForm { inner_value, .. } => inner_value.is_nil(), + OptForm::Pair(_a,_b) => true, + _ => false, + })), c, metac }, + PrimCombI::SymbolP => Cursor { f: Rc::new(OptForm::Bool(match &*ps[0] { + // TODO OptForm::CodeForm { inner_value, .. } => inner_value.is_nil(), OptForm::Symbol(_) => true, + _ => false, + })), c, metac }, + PrimCombI::IntP => Cursor { f: Rc::new(OptForm::Bool(match &*ps[0] { + // TODO OptForm::CodeForm { inner_value, .. } => inner_value.is_nil(), + OptForm::Int(_) => true, _ => false, })), c, metac }, - PrimCombI::IntP => Cursor { f: Rc::new(OptForm::Bool(match &*ps.car().unwrap() { - OptForm::Int(_) => true, - _ => false, - })), c, metac }, - PrimCombI::BoolP => Cursor { f: Rc::new(OptForm::Bool(match &*ps.car().unwrap() { + PrimCombI::BoolP => Cursor { f: Rc::new(OptForm::Bool(match &*ps[0] { + // TODO OptForm::CodeForm { inner_value, .. } => inner_value.is_nil(), OptForm::Bool(_) => true, _ => false, })), c, metac }, - PrimCombI::NilP => Cursor { f: Rc::new(OptForm::Bool(ps.car().unwrap().is_nil())), c, metac }, + PrimCombI::NilP => Cursor { f: Rc::new(OptForm::Bool(ps[0].is_nil())), c, metac }, } } }