Implement PartialEq and PartialOrd resolves #7

This commit is contained in:
2021-05-30 12:25:20 -04:00
parent e070441c31
commit 1da08c0a43
5 changed files with 40 additions and 17 deletions

1
.gitignore vendored
View File

@@ -7,3 +7,4 @@
**/*.rs.bk **/*.rs.bk
.vscode .vscode
test.scm

View File

@@ -19,6 +19,7 @@ pub fn get_global_environment<'a>() -> Env<'a> {
(make_symbol("*"), Datum::Procedure(primitives::mul)), (make_symbol("*"), Datum::Procedure(primitives::mul)),
(make_symbol("-"), Datum::Procedure(primitives::sub)), (make_symbol("-"), Datum::Procedure(primitives::sub)),
(make_symbol("="), Datum::Procedure(primitives::eq)), (make_symbol("="), Datum::Procedure(primitives::eq)),
(make_symbol("<"), Datum::Procedure(primitives::lt)),
], ],
outer: None, outer: None,
} }
@@ -80,8 +81,3 @@ pub fn extend<'a>(vars: Datum, vals: Datum, env: &'a Env) -> Env<'a> {
outer: Some(env), outer: Some(env),
} }
} }
// pub fn shrink_environment(env: &mut Env) -> Datum {
// env.pop();
// Datum::Unspecified
// }

View File

@@ -61,6 +61,8 @@ fn interpret_define(args: &Vec<Datum>, env: &mut Env) -> Datum {
panic!("INTERPRET-DEFINE -- parameter not a symbol {:?}", p); 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_parameters = Datum::List(parameters);
let lambda_body = Datum::List(args[2..].to_vec()); let lambda_body = Datum::List(args[2..].to_vec());
let lambda = Datum::List(vec![make_symbol("lambda"), lambda_parameters, lambda_body]); let lambda = Datum::List(vec![make_symbol("lambda"), lambda_parameters, lambda_body]);

View File

@@ -1,5 +1,6 @@
use crate::lexer::Token; use crate::lexer::Token;
use crate::lexer::Tokens; use crate::lexer::Tokens;
use std::cmp::Ordering;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Datum { 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<Ordering> {
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 { pub fn parse(tokens: Tokens) -> Datum {
let (datum, _) = parse_datum(&tokens, 0); let (datum, _) = parse_datum(&tokens, 0);
datum datum

View File

@@ -62,20 +62,23 @@ pub fn eq(args: Vec<Datum>) -> Datum {
Boolean(true) Boolean(true)
} else { } else {
let first = &args[1]; let first = &args[1];
for i in 2..args.len() { for i in 2..args.len() {
let current = &args[i]; let current = &args[i];
match (first, current) { if first != current {
(Boolean(b1), Boolean(b2)) => { return Boolean(false);
return Boolean(b1 == b2); }
} }
(Number(n1), Number(n2)) => { Boolean(true)
return Boolean(n1 == n2); }
} }
_ => {
println!("{:?} is not equal to {:?}", first, current); pub fn lt(args: Vec<Datum>) -> Datum {
return Boolean(false); 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) Boolean(true)