Implemented Display for Form, then first sketch of MarkedForm, NeededIds, and unval, and Display for MarkedForm
This commit is contained in:
24
flake.lock
generated
24
flake.lock
generated
@@ -2,11 +2,11 @@
|
|||||||
"nodes": {
|
"nodes": {
|
||||||
"flake-utils": {
|
"flake-utils": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1667395993,
|
"lastModified": 1676283394,
|
||||||
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
"narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "flake-utils",
|
"repo": "flake-utils",
|
||||||
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
"rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -36,11 +36,11 @@
|
|||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1673836088,
|
"lastModified": 1676341851,
|
||||||
"narHash": "sha256-cAlfrHbX9sLcRdydMP8vhyxZChlVHqkEkumgc2LK4FY=",
|
"narHash": "sha256-T8cmSiriXdpZfqlserNyJ1solTCR0DbD8A75epSDOVY=",
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"rev": "8f201a1adfddf715b708befd18164c8cbe65a268",
|
"rev": "956ddb5047f98ea08b792b22004b94a9971932c4",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -67,11 +67,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_stable_new": {
|
"nixpkgs_stable_new": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1673800717,
|
"lastModified": 1676177817,
|
||||||
"narHash": "sha256-SFHraUqLSu5cC6IxTprex/nTsI81ZQAtDvlBvGDWfnA=",
|
"narHash": "sha256-OQnBnuKkpwkfNY31xQyfU5hNpLs1ilWt+hVY6ztEEOM=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "2f9fd351ec37f5d479556cd48be4ca340da59b8f",
|
"rev": "1b82144edfcd0c86486d2e07c7298f85510e7fb8",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -97,11 +97,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_unstable": {
|
"nixpkgs_unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1673914939,
|
"lastModified": 1676342081,
|
||||||
"narHash": "sha256-CfsyGi3y/ok7se6wd/OD+F8muVRZ1zYdE/0wsV2C/u8=",
|
"narHash": "sha256-zpHbXgvUYTJ9r1WgKtwhj/dmVthZ/GlW1oBYOdqJ9yg=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "341aa70d1e5098d6c01791e1175baa84793b3aae",
|
"rev": "4106c7519bff1d14fa5f942da645b3f18d16309e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
129
kr/src/ast.rs
129
kr/src/ast.rs
@@ -1,5 +1,8 @@
|
|||||||
|
use std::fmt;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
|
use std::collections::BTreeSet;
|
||||||
|
use std::result::Result;
|
||||||
|
|
||||||
impl From<i32> for Form { fn from(item: i32) -> Self { Form::Int(item) } }
|
impl From<i32> for Form { fn from(item: i32) -> Self { Form::Int(item) } }
|
||||||
impl From<bool> for Form { fn from(item: bool) -> Self { Form::Bool(item) } }
|
impl From<bool> for Form { fn from(item: bool) -> Self { Form::Bool(item) } }
|
||||||
@@ -25,7 +28,7 @@ pub enum Form {
|
|||||||
Symbol(String),
|
Symbol(String),
|
||||||
Pair(Rc<Form>,Rc<Form>),
|
Pair(Rc<Form>,Rc<Form>),
|
||||||
PrimComb(String, fn(Rc<Form>, Rc<Form>) -> PossibleTailCall),
|
PrimComb(String, fn(Rc<Form>, Rc<Form>) -> PossibleTailCall),
|
||||||
DeriComb { se: Rc<Form>, de: Option<String>, params: Rc<Form>, body: Rc<Form> },
|
DeriComb { se: Rc<Form>, de: Option<String>, params: String, body: Rc<Form> },
|
||||||
}
|
}
|
||||||
impl Form {
|
impl Form {
|
||||||
pub fn truthy(&self) -> bool {
|
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<Form> = 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<i32>),
|
||||||
|
}
|
||||||
|
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<MarkedForm>),
|
||||||
|
TailCall(Rc<MarkedForm>, Rc<MarkedForm>),
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
pub enum MarkedForm {
|
||||||
|
Value(Rc<Form>),
|
||||||
|
SuspendedSymbol { ids: NeededIds, name: String, crdi_carb: Option<(i32, bool)> },
|
||||||
|
|
||||||
|
SuspendedPair(NeededIds, Rc<MarkedForm>, Rc<MarkedForm>),
|
||||||
|
|
||||||
|
PrimComb { name: String, wrap_level: i32, f: fn(Rc<MarkedForm>, Rc<MarkedForm>) -> PossibleMarkedTailCall },
|
||||||
|
|
||||||
|
DeriComb { ids: NeededIds, se: Rc<MarkedForm>, de: Option<String>, id: i32, wrap_level: i32, sequence_params: Vec<String>, rest_params: Option<String>, body: Rc<MarkedForm> },
|
||||||
|
}
|
||||||
|
impl MarkedForm {
|
||||||
|
pub fn unval(self: &Rc<MarkedForm>) -> Result<Rc<MarkedForm>, &'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<MarkedForm> = 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(());
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ lalrpop_mod!(pub grammar);
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
mod ast;
|
mod ast;
|
||||||
use crate::ast::{Form,PossibleTailCall};
|
use crate::ast::{MarkedForm,Form,PossibleTailCall};
|
||||||
|
|
||||||
fn eval(e: Rc<Form>, f: Rc<Form>) -> Rc<Form> {
|
fn eval(e: Rc<Form>, f: Rc<Form>) -> Rc<Form> {
|
||||||
let mut e = e;
|
let mut e = e;
|
||||||
@@ -37,9 +37,7 @@ fn eval(e: Rc<Form>, f: Rc<Form>) -> Rc<Form> {
|
|||||||
if let Some(de) = de {
|
if let Some(de) = de {
|
||||||
new_e = assoc(de, Rc::clone(&e), new_e);
|
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
|
// always a tail call
|
||||||
e = new_e;
|
e = new_e;
|
||||||
x = Some(Rc::clone(body));
|
x = Some(Rc::clone(body));
|
||||||
@@ -82,7 +80,7 @@ fn root_env() -> Rc<Form> {
|
|||||||
// (vau de params body)
|
// (vau de params body)
|
||||||
("vau", Rc::new(Form::PrimComb("vau".to_owned(), |e, p| {
|
("vau", Rc::new(Form::PrimComb("vau".to_owned(), |e, p| {
|
||||||
let de = p.car().unwrap().sym().map(|s| s.to_owned());
|
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();
|
let body = p.cdr().unwrap().cdr().unwrap().car().unwrap();
|
||||||
|
|
||||||
PossibleTailCall::Result(Rc::new(Form::DeriComb { se: e, de, params, body }))
|
PossibleTailCall::Result(Rc::new(Form::DeriComb { se: e, de, params, body }))
|
||||||
@@ -219,10 +217,11 @@ fn root_env() -> Rc<Form> {
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let input = "(= 17 ((vau d p (+ (eval (car p) d) 13)) (+ 1 3)))";
|
let input = "(= 17 ((vau d p (+ (eval (car p) d) 13)) (+ 1 3)))";
|
||||||
let parsed_input = grammar::TermParser::new().parse(input).unwrap();
|
let parsed_input = Rc::new(grammar::TermParser::new().parse(input).unwrap());
|
||||||
println!("Parsed input is {:?}", parsed_input);
|
println!("Parsed input is {} - {:?}", parsed_input, parsed_input);
|
||||||
let result = eval(root_env(), Rc::new(parsed_input));
|
println!("Parsed unvaled that is {}", Rc::new(MarkedForm::Value(Rc::clone(&parsed_input))).unval().unwrap());
|
||||||
println!("Result is {:?}", result);
|
let result = eval(root_env(), parsed_input);
|
||||||
|
println!("Result is {} - {:?}", result, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user