Implement PartialEq and PartialOrd resolves #7
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,3 +7,4 @@
|
||||
**/*.rs.bk
|
||||
|
||||
.vscode
|
||||
test.scm
|
||||
|
||||
@@ -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
|
||||
// }
|
||||
|
||||
@@ -61,6 +61,8 @@ fn interpret_define(args: &Vec<Datum>, 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]);
|
||||
|
||||
@@ -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<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 {
|
||||
let (datum, _) = parse_datum(&tokens, 0);
|
||||
datum
|
||||
|
||||
@@ -62,20 +62,23 @@ pub fn eq(args: Vec<Datum>) -> 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>) -> 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)
|
||||
|
||||
Reference in New Issue
Block a user