From 1da08c0a43083bfbace5093c715010c7fc8eb90c Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Sun, 30 May 2021 12:25:20 -0400 Subject: [PATCH] Implement PartialEq and PartialOrd resolves #7 --- .gitignore | 1 + src/environment.rs | 6 +----- src/interpreter.rs | 2 ++ src/parser.rs | 21 +++++++++++++++++++++ src/primitives.rs | 27 +++++++++++++++------------ 5 files changed, 40 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 765cf3b..605cef0 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ **/*.rs.bk .vscode +test.scm diff --git a/src/environment.rs b/src/environment.rs index 0afdb2d..abac38f 100644 --- a/src/environment.rs +++ b/src/environment.rs @@ -19,6 +19,7 @@ pub fn get_global_environment<'a>() -> Env<'a> { (make_symbol("*"), Datum::Procedure(primitives::mul)), (make_symbol("-"), Datum::Procedure(primitives::sub)), (make_symbol("="), Datum::Procedure(primitives::eq)), + (make_symbol("<"), Datum::Procedure(primitives::lt)), ], outer: None, } @@ -80,8 +81,3 @@ pub fn extend<'a>(vars: Datum, vals: Datum, env: &'a Env) -> Env<'a> { outer: Some(env), } } - -// pub fn shrink_environment(env: &mut Env) -> Datum { -// env.pop(); -// Datum::Unspecified -// } diff --git a/src/interpreter.rs b/src/interpreter.rs index ecbbfc7..1977b1f 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -61,6 +61,8 @@ fn interpret_define(args: &Vec, env: &mut Env) -> Datum { panic!("INTERPRET-DEFINE -- parameter not a symbol {:?}", p); } } + // FIXME: we need to keep the current environment here otherwise closures will not work + // FIXME: also create a dedicated enum-type for procedures instead of putting it into a vector let lambda_parameters = Datum::List(parameters); let lambda_body = Datum::List(args[2..].to_vec()); let lambda = Datum::List(vec![make_symbol("lambda"), lambda_parameters, lambda_body]); diff --git a/src/parser.rs b/src/parser.rs index a0bb0bc..d9bf201 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,5 +1,6 @@ use crate::lexer::Token; use crate::lexer::Tokens; +use std::cmp::Ordering; #[derive(Debug, Clone)] pub enum Datum { @@ -21,6 +22,26 @@ impl Default for Datum { } } +impl PartialEq for Datum { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Datum::Boolean(b1), Datum::Boolean(b2)) => b1 == b2, + (Datum::Number(n1), Datum::Number(n2)) => n1 == n2, + _ => false, + } + } +} + +impl PartialOrd for Datum { + fn partial_cmp(&self, other: &Self) -> Option { + match (self, other) { + (Datum::Boolean(b1), Datum::Boolean(b2)) => Some(b1.cmp(b2)), + (Datum::Number(n1), Datum::Number(n2)) => Some(n1.cmp(n2)), + _ => None, + } + } +} + pub fn parse(tokens: Tokens) -> Datum { let (datum, _) = parse_datum(&tokens, 0); datum diff --git a/src/primitives.rs b/src/primitives.rs index 3bd0427..0cd7744 100644 --- a/src/primitives.rs +++ b/src/primitives.rs @@ -62,20 +62,23 @@ pub fn eq(args: Vec) -> Datum { Boolean(true) } else { let first = &args[1]; - for i in 2..args.len() { let current = &args[i]; - match (first, current) { - (Boolean(b1), Boolean(b2)) => { - return Boolean(b1 == b2); - } - (Number(n1), Number(n2)) => { - return Boolean(n1 == n2); - } - _ => { - println!("{:?} is not equal to {:?}", first, current); - return Boolean(false); - } + if first != current { + return Boolean(false); + } + } + Boolean(true) + } +} + +pub fn lt(args: Vec) -> Datum { + if args.len() == 1 { + Boolean(true) + } else { + for i in 1..(args.len() - 1) { + if &args[i] >= &args[i + 1] { + return Boolean(false); } } Boolean(true)