From 66fc1db6068c48ab42251bb608d4db4e1aa6526c Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Tue, 14 Feb 2023 00:50:05 -0500 Subject: [PATCH] Implemented Display for Form, then first sketch of MarkedForm, NeededIds, and unval, and Display for MarkedForm --- flake.lock | 24 ++++----- kr/src/ast.rs | 129 ++++++++++++++++++++++++++++++++++++++++++++++++- kr/src/main.rs | 17 +++---- 3 files changed, 148 insertions(+), 22 deletions(-) diff --git a/flake.lock b/flake.lock index 8c910e6..eb27d87 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "flake-utils": { "locked": { - "lastModified": 1667395993, - "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "lastModified": 1676283394, + "narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=", "owner": "numtide", "repo": "flake-utils", - "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073", "type": "github" }, "original": { @@ -36,11 +36,11 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1673836088, - "narHash": "sha256-cAlfrHbX9sLcRdydMP8vhyxZChlVHqkEkumgc2LK4FY=", + "lastModified": 1676341851, + "narHash": "sha256-T8cmSiriXdpZfqlserNyJ1solTCR0DbD8A75epSDOVY=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "8f201a1adfddf715b708befd18164c8cbe65a268", + "rev": "956ddb5047f98ea08b792b22004b94a9971932c4", "type": "github" }, "original": { @@ -67,11 +67,11 @@ }, "nixpkgs_stable_new": { "locked": { - "lastModified": 1673800717, - "narHash": "sha256-SFHraUqLSu5cC6IxTprex/nTsI81ZQAtDvlBvGDWfnA=", + "lastModified": 1676177817, + "narHash": "sha256-OQnBnuKkpwkfNY31xQyfU5hNpLs1ilWt+hVY6ztEEOM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "2f9fd351ec37f5d479556cd48be4ca340da59b8f", + "rev": "1b82144edfcd0c86486d2e07c7298f85510e7fb8", "type": "github" }, "original": { @@ -97,11 +97,11 @@ }, "nixpkgs_unstable": { "locked": { - "lastModified": 1673914939, - "narHash": "sha256-CfsyGi3y/ok7se6wd/OD+F8muVRZ1zYdE/0wsV2C/u8=", + "lastModified": 1676342081, + "narHash": "sha256-zpHbXgvUYTJ9r1WgKtwhj/dmVthZ/GlW1oBYOdqJ9yg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "341aa70d1e5098d6c01791e1175baa84793b3aae", + "rev": "4106c7519bff1d14fa5f942da645b3f18d16309e", "type": "github" }, "original": { diff --git a/kr/src/ast.rs b/kr/src/ast.rs index df8e451..e0bec78 100644 --- a/kr/src/ast.rs +++ b/kr/src/ast.rs @@ -1,5 +1,8 @@ +use std::fmt; use std::rc::Rc; use std::convert::From; +use std::collections::BTreeSet; +use std::result::Result; impl From for Form { fn from(item: i32) -> Self { Form::Int(item) } } impl From for Form { fn from(item: bool) -> Self { Form::Bool(item) } } @@ -25,7 +28,7 @@ pub enum Form { Symbol(String), Pair(Rc
,Rc), PrimComb(String, fn(Rc, Rc) -> PossibleTailCall), - DeriComb { se: Rc, de: Option, params: Rc, body: Rc }, + DeriComb { se: Rc, de: Option, params: String, body: Rc }, } impl Form { pub fn truthy(&self) -> bool { @@ -67,4 +70,128 @@ impl Form { } } } +impl fmt::Display for Form { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Form::Nil => write!(f, "nil"), + Form::Int(i) => write!(f, "{}", i), + Form::Bool(b) => write!(f, "{}", b), + Form::Symbol(s) => write!(f, "{}", s), + Form::Pair(car, cdr) => { + write!(f, "({}", car)?; + let mut traverse: Rc = Rc::clone(cdr); + loop { + match &*traverse { + Form::Pair(ref carp, ref cdrp) => { + write!(f, " {}", carp)?; + traverse = Rc::clone(cdrp); + }, + Form::Nil => { + write!(f, ")")?; + return Ok(()); + }, + x => { + write!(f, ". {})", x)?; + return Ok(()); + }, + } + } + }, + Form::PrimComb(name, _f) => write!(f, "<{}>", name), + Form::DeriComb { se, de, params, body } => { + write!(f, "<{} {} {}>", de.as_ref().unwrap_or(&"".to_string()), params, body) + }, + } + } +} +#[derive(Debug, Clone, Eq, PartialEq)] +pub enum NeededIds { + True, + None, + Some(BTreeSet), +} +impl NeededIds { + fn union(&self, other: &NeededIds) -> Self { + match self { + NeededIds::True => NeededIds::True, + NeededIds::None => other.clone(), + NeededIds::Some(set) => match other { + NeededIds::True => NeededIds::True, + NeededIds::None => self.clone(), + NeededIds::Some(oset) => NeededIds::Some(set.union(oset).cloned().collect()), + }, + } + } +} +pub enum PossibleMarkedTailCall { + Result(Rc), + TailCall(Rc, Rc), +} +#[derive(Debug, Clone, Eq, PartialEq)] +pub enum MarkedForm { + Value(Rc), + SuspendedSymbol { ids: NeededIds, name: String, crdi_carb: Option<(i32, bool)> }, + + SuspendedPair(NeededIds, Rc, Rc), + + PrimComb { name: String, wrap_level: i32, f: fn(Rc, Rc) -> PossibleMarkedTailCall }, + + DeriComb { ids: NeededIds, se: Rc, de: Option, id: i32, wrap_level: i32, sequence_params: Vec, rest_params: Option, body: Rc }, +} +impl MarkedForm { + pub fn unval(self: &Rc) -> Result, &'static str> { + match &**self { + MarkedForm::Value(form) => { + match &**form { + Form::Nil => Ok(Rc::clone(self)), + Form::Int(i)=> Ok(Rc::clone(self)), + Form::Bool(b)=> Ok(Rc::clone(self)), + Form::PrimComb(n, f)=> Err("tried to unval a PrimComb that was the simpler version, need to figure this out"), + Form::DeriComb { se, de, params, body }=> Ok(Rc::clone(self)), + + Form::Symbol(s) => Ok(Rc::new(MarkedForm::SuspendedSymbol { ids: NeededIds::True, name: s.clone(), crdi_carb: None })), + Form::Pair(car,cdr) => Ok(Rc::new(MarkedForm::SuspendedPair( NeededIds::True, + Rc::new(MarkedForm::Value(Rc::clone(car))).unval()?, + Rc::new(MarkedForm::Value(Rc::clone(cdr))).unval()? ))), + } + }, + MarkedForm::SuspendedSymbol { ids, name, crdi_carb } => Err("trying to unval a suspended symbol"), + MarkedForm::SuspendedPair(ids, car, cdr) => Err("trying to unval a suspended pair"), + MarkedForm::PrimComb { name, wrap_level, f } => Ok(Rc::clone(self)), + MarkedForm::DeriComb { ids, se, de, id, wrap_level, sequence_params, rest_params, body } => Ok(Rc::clone(self)), + } + } +} +impl fmt::Display for MarkedForm { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + MarkedForm::Value(form) => write!(f, "{}", form), + MarkedForm::SuspendedSymbol { ids, name, crdi_carb } => write!(f, "{:?}#{}({:?})", ids, name, crdi_carb), + 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::SuspendedPair(ids, car, cdr) => { + write!(f, "{:?}#{{{}", ids, car)?; + let mut traverse: Rc = Rc::clone(cdr); + loop { + match &*traverse { + MarkedForm::SuspendedPair(ref _ids, ref carp, ref cdrp) => { + write!(f, " {}", carp)?; + traverse = Rc::clone(cdrp); + }, + MarkedForm::Value(form) if match &**form { Form::Nil => true, _ => false } => { + write!(f, "}}")?; + return Ok(()); + }, + x => { + write!(f, ". {}}}", x)?; + return Ok(()); + }, + } + } + }, + } + } +} diff --git a/kr/src/main.rs b/kr/src/main.rs index f349dcf..a8b7441 100644 --- a/kr/src/main.rs +++ b/kr/src/main.rs @@ -4,7 +4,7 @@ lalrpop_mod!(pub grammar); use std::rc::Rc; mod ast; -use crate::ast::{Form,PossibleTailCall}; +use crate::ast::{MarkedForm,Form,PossibleTailCall}; fn eval(e: Rc, f: Rc) -> Rc { let mut e = e; @@ -37,9 +37,7 @@ fn eval(e: Rc, f: Rc) -> Rc { if let Some(de) = de { new_e = assoc(de, Rc::clone(&e), new_e); } - if let Some(params) = params.sym() { - new_e = assoc(params, Rc::clone(p), new_e); - } + new_e = assoc(params, Rc::clone(p), new_e); // always a tail call e = new_e; x = Some(Rc::clone(body)); @@ -82,7 +80,7 @@ fn root_env() -> Rc { // (vau de params body) ("vau", Rc::new(Form::PrimComb("vau".to_owned(), |e, p| { let de = p.car().unwrap().sym().map(|s| s.to_owned()); - let params = p.cdr().unwrap().car().unwrap(); + let params = p.cdr().unwrap().car().unwrap().sym().unwrap().to_owned(); let body = p.cdr().unwrap().cdr().unwrap().car().unwrap(); PossibleTailCall::Result(Rc::new(Form::DeriComb { se: e, de, params, body })) @@ -219,10 +217,11 @@ fn root_env() -> Rc { fn main() { let input = "(= 17 ((vau d p (+ (eval (car p) d) 13)) (+ 1 3)))"; - let parsed_input = grammar::TermParser::new().parse(input).unwrap(); - println!("Parsed input is {:?}", parsed_input); - let result = eval(root_env(), Rc::new(parsed_input)); - println!("Result is {:?}", result); + let parsed_input = Rc::new(grammar::TermParser::new().parse(input).unwrap()); + println!("Parsed input is {} - {:?}", parsed_input, parsed_input); + println!("Parsed unvaled that is {}", Rc::new(MarkedForm::Value(Rc::clone(&parsed_input))).unval().unwrap()); + let result = eval(root_env(), parsed_input); + println!("Result is {} - {:?}", result, result); } #[test]