Skip to content

Commit

Permalink
no need for expression & re-evaluate before passing
Browse files Browse the repository at this point in the history
  • Loading branch information
orzklv committed Aug 7, 2023
1 parent 74ce760 commit bf14261
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 71 deletions.
11 changes: 9 additions & 2 deletions src/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,15 @@ impl Environment {
}
}

pub fn define(&mut self, name: Expression, value: Expression) -> Expression {
self.variables.insert(name.to_string(), value.clone());
pub fn define(
&mut self,
name: Expression,
value: Expression
) -> Expression {
self.variables.insert(
name.to_string(),
value.clone(),
);
value
}

Expand Down
12 changes: 12 additions & 0 deletions src/expression.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::convert::TryFrom;
use std::fmt::Debug;

#[derive(PartialEq, Clone, Debug)]
Expand All @@ -11,6 +12,17 @@ pub enum Expression {
Divide(Vec<Expression>),
}

impl TryFrom<Expression> for i64 {
type Error = &'static str;

fn try_from(value: Expression) -> Result<Self, Self::Error> {
match value {
Expression::Number(n) => Ok(n),
_ => Err("Cannot convert non-number Expression to i64"),
}
}
}

impl std::fmt::Display for Expression {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Expand Down
134 changes: 84 additions & 50 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#![allow(clippy::match_single_binding)]

mod environment;
mod error;
mod expression;
mod result;

use environment::Environment;
use error::SchierkeError;
use expression::Expression;
use result::SchierkeResult;

#[derive(Default, PartialEq)]
#[derive(Default, PartialEq, Clone)]
pub struct Schierke {
global: Environment,
}
Expand All @@ -24,23 +24,23 @@ impl Schierke {
&mut self,
exp: Expression,
env: Option<Environment>,
) -> Result<SchierkeResult, SchierkeError> {
) -> Result<Expression, SchierkeError> {
let mut _e: Environment = match env {
Some(e) => e,
None => self.global.clone(),
};

let rev = match exp.clone() {
Expression::Number(e) => Ok(SchierkeResult::Number(e)),
Expression::String(e) => Ok(SchierkeResult::String(e)),
let rev: Result<Expression, SchierkeError> = match exp.clone() {
Expression::Number(e) => Ok(Expression::Number(e)),
Expression::String(e) => Ok(Expression::String(e)),
Expression::Variable(e) => match e.len() {
1 => {
let result = _e.lookup(e[0].clone().to_string());
Ok(SchierkeResult::Expression(result.unwrap()))
Ok(result.unwrap())
}
2 => {
let result = _e.define(e[0].clone(), e[1].clone());
Ok(SchierkeResult::Expression(result))
let result = _e.define(e[0].clone(), self.eval(e[1].clone(), None).unwrap());
Ok(result)
}
_ => Err(SchierkeError::TooMuchArguments),
},
Expand All @@ -55,41 +55,51 @@ impl Schierke {
let mut result = 0;

result += match self.eval(e[0].clone(), None)? {
SchierkeResult::Number(n) => n,
_ => return Err(SchierkeError::UnknownExpression),
n => match i64::try_from(n) {
Ok(n) => n,
Err(_) => return Err(SchierkeError::UnknownExpression),
},
};

match exp.clone() {
Expression::Add(_) => {
result += match self.eval(e[1].clone(), None)? {
SchierkeResult::Number(n) => n,
_ => return Err(SchierkeError::UnknownExpression),
n => match i64::try_from(n) {
Ok(n) => n,
Err(_) => return Err(SchierkeError::UnknownExpression),
},
};
}
Expression::Subtract(_) => {
result -= match self.eval(e[1].clone(), None)? {
SchierkeResult::Number(n) => n,
_ => return Err(SchierkeError::UnknownExpression),
};
n => match i64::try_from(n) {
Ok(n) => n,
Err(_) => return Err(SchierkeError::UnknownExpression),
}
}
}
Expression::Multiply(_) => {
result *= match self.eval(e[1].clone(), None)? {
SchierkeResult::Number(n) => n,
_ => return Err(SchierkeError::UnknownExpression),
n => match i64::try_from(n) {
Ok(n) => n,
Err(_) => return Err(SchierkeError::UnknownExpression),
},
};
}
Expression::Divide(_) => {
result /= match self.eval(e[1].clone(), None)? {
SchierkeResult::Number(n) => n,
_ => return Err(SchierkeError::UnknownExpression),
n => match i64::try_from(n) {
Ok(n) => n,
Err(_) => return Err(SchierkeError::UnknownExpression),
},
};
}
_ => {
return Err(SchierkeError::UnknownExpression);
}
};

Ok(SchierkeResult::Number(result))
Ok(Expression::Number(result))
}
};

Expand All @@ -103,26 +113,25 @@ impl Schierke {
mod tests {
use super::Expression;
use super::Schierke;
use crate::result::SchierkeResult;

#[test]
fn number() {
let mut schierke = Schierke::new();

// Number expression
let exp = Expression::Number(2);
assert_eq!(schierke.eval(exp, None), Ok(SchierkeResult::Number(2)));
let expression = Expression::Number(2);
assert_eq!(schierke.eval(expression, None), Ok(Expression::Number(2)));
}

#[test]
fn string() {
let mut schierke = Schierke::new();

// String expression
let exp = Expression::String("hello".to_string());
let expression = Expression::String("hello".to_string());
assert_eq!(
schierke.eval(exp, None),
Ok(SchierkeResult::String("hello".to_string()))
schierke.eval(expression, None),
Ok(Expression::String("hello".to_string()))
);
}

Expand All @@ -131,70 +140,95 @@ mod tests {
let mut schierke = Schierke::new();

// Add expression
let exp = Expression::Add(vec![Expression::Number(2), Expression::Number(2)]);
assert_eq!(schierke.eval(exp, None), Ok(SchierkeResult::Number(4)));
let expression = Expression::Add(vec![Expression::Number(2), Expression::Number(2)]);
assert_eq!(schierke.eval(expression, None), Ok(Expression::Number(4)));
}

#[test]
fn add_complex() {
let mut schierke = Schierke::new();

// More complex add expression
let exp = Expression::Add(vec![
let expression = Expression::Add(vec![
Expression::Number(2),
Expression::Add(vec![Expression::Number(2), Expression::Number(2)]),
]);

assert_eq!(schierke.eval(exp, None), Ok(SchierkeResult::Number(6)));
assert_eq!(schierke.eval(expression, None), Ok(Expression::Number(6)));
}

#[test]
fn subtract() {
let mut schierke = Schierke::new();

// Subtract expression
let exp = Expression::Subtract(vec![Expression::Number(2), Expression::Number(2)]);
assert_eq!(schierke.eval(exp, None), Ok(SchierkeResult::Number(0)));
let expression = Expression::Subtract(vec![Expression::Number(2), Expression::Number(2)]);
assert_eq!(schierke.eval(expression, None), Ok(Expression::Number(0)));
}

#[test]
fn subtract_complex() {
let mut schierke = Schierke::new();

// More complex subtract expression
let exp = Expression::Subtract(vec![
let expression = Expression::Subtract(vec![
Expression::Number(2),
Expression::Subtract(vec![Expression::Number(2), Expression::Number(2)]),
]);

assert_eq!(schierke.eval(exp, None), Ok(SchierkeResult::Number(2)));
assert_eq!(schierke.eval(expression, None), Ok(Expression::Number(2)));
}

#[test]
fn multiply() {
let mut schierke = Schierke::new();

// Multiply expression
let exp = Expression::Multiply(vec![Expression::Number(4), Expression::Number(3)]);
assert_eq!(schierke.eval(exp, None), Ok(SchierkeResult::Number(12)));
let expression = Expression::Multiply(vec![Expression::Number(4), Expression::Number(3)]);
assert_eq!(schierke.eval(expression, None), Ok(Expression::Number(12)));
}

#[test]
fn multiply_complex() {
let mut schierke = Schierke::new();

// More complex multiply expression
let exp = Expression::Multiply(vec![
let expression = Expression::Multiply(vec![
Expression::Number(4),
Expression::Multiply(vec![Expression::Number(3), Expression::Number(2)]),
]);
assert_eq!(schierke.eval(exp, None), Ok(SchierkeResult::Number(24)));
assert_eq!(schierke.eval(expression, None), Ok(Expression::Number(24)));
}

#[test]
fn variable() {
let mut schierke = Schierke::new();

// Variable set expression
let exp = Expression::Variable(vec![
let expression = Expression::Variable(vec![
Expression::String("x".to_string()),
Expression::Number(2),
]);
assert_eq!(
schierke.eval(exp, None),
Ok(SchierkeResult::Expression(Expression::Number(2)))
);
assert_eq!(schierke.eval(expression, None), Ok(Expression::Number(2)));

// Variable get expression
let exp = Expression::Variable(vec![Expression::String("x".to_string())]);
assert_eq!(
schierke.eval(exp, None),
Ok(SchierkeResult::Expression(Expression::Number(2)))
);
let expression = Expression::Variable(vec![Expression::String("x".to_string())]);
assert_eq!(schierke.eval(expression, None), Ok(Expression::Number(2)));
}

#[test]
fn variable_complex() {
let mut schierke = Schierke::new();

// Variable set expression but way more complex
let expression = Expression::Variable(vec![
Expression::String("x".to_string()),
Expression::Add(vec![Expression::Number(2), Expression::Add(vec![Expression::Number(2), Expression::Number(2)])]),
]);
assert_eq!(schierke.eval(expression, None), Ok(Expression::Number(6)));

// Variable get expression but way more complex
let expression = Expression::Variable(vec![Expression::String("x".to_string())]);
assert_eq!(schierke.eval(expression, None), Ok(Expression::Number(6)));
}
}
19 changes: 0 additions & 19 deletions src/result.rs

This file was deleted.

0 comments on commit bf14261

Please sign in to comment.