Skip to content

Commit

Permalink
Refactor string object and string evaluation logic
Browse files Browse the repository at this point in the history
  • Loading branch information
DaviRain-Su committed Oct 10, 2023
1 parent 8183c1c commit da97263
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 46 deletions.
22 changes: 9 additions & 13 deletions src/evaluator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,9 @@ pub fn eval(node: Node, env: &mut Environment) -> anyhow::Result<Object> {

apply_function(function, args)
}
Expression::StringLiteral(string_literal) => Ok(StringObj {
value: string_literal.value.clone(),
Expression::StringLiteral(string_literal) => {
Ok(StringObj::new(string_literal.value.clone()).into())
}
.into()),
Expression::ArrayLiteral(array) => {
let elements = eval_expressions(array.elements().clone(), env)?;

Expand Down Expand Up @@ -254,23 +253,20 @@ fn eval_string_infix_expression(
) -> anyhow::Result<Object> {
match operator.as_str() {
"+" => {
let left_val = left.value;
let right_val = right.value;
let left_val = left.value();
let right_val = right.value();

Ok(StringObj {
value: format!("{left_val}{right_val}"),
}
.into())
Ok(StringObj::new(format!("{left_val}{right_val}")).into())
}
"==" => {
let left_val = left.value;
let right_val = right.value;
let left_val = left.value();
let right_val = right.value();

Ok(Boolean::new(left_val == right_val).into())
}
"!=" => {
let left_val = left.value;
let right_val = right.value;
let left_val = left.value();
let right_val = right.value();

Ok(Boolean::new(left_val != right_val).into())
}
Expand Down
29 changes: 7 additions & 22 deletions src/evaluator/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,8 +612,8 @@ fn test_string_literal() -> anyhow::Result<()> {
let str_lit = StringObj::try_from(evaluated)?;
println!("test string literal = {:?}", str_lit);

if str_lit.value != "Hello World!" {
eprintln!("String has wrong value. got = {}", str_lit.value);
if str_lit.value() != "Hello World!" {
eprintln!("String has wrong value. got = {}", str_lit.value());
}
Ok(())
}
Expand All @@ -624,10 +624,10 @@ fn test_string_concatenation() -> anyhow::Result<()> {
let evaluated = test_eval(input.to_string())?;
let str_lit = StringObj::try_from(evaluated)?;

if str_lit.value != "Hello World!" {
if str_lit.value() != "Hello World!" {
return Err(anyhow::anyhow!(format!(
"String has wrong value. got = {}",
str_lit.value
str_lit.value()
)));
}

Expand Down Expand Up @@ -860,24 +860,9 @@ let two = "two";
let result = Hash::try_from(evaluated)?;

let mut expected = BTreeMap::<Object, i64>::new();
expected.insert(
Object::String(StringObj {
value: "one".to_string(),
}),
1,
);
expected.insert(
Object::String(StringObj {
value: "two".to_string(),
}),
2,
);
expected.insert(
Object::String(StringObj {
value: "three".to_string(),
}),
3,
);
expected.insert(Object::String(StringObj::new("one".to_string())), 1);
expected.insert(Object::String(StringObj::new("two".to_string())), 2);
expected.insert(Object::String(StringObj::new("three".to_string())), 3);
expected.insert(Object::Integer(Integer { value: 4 }), 4);
expected.insert(Object::Boolean(*TRUE), 5);
expected.insert(Object::Boolean(*FALSE), 6);
Expand Down
2 changes: 1 addition & 1 deletion src/object/built_in_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub fn process_len(args: Vec<Object>) -> anyhow::Result<Object> {

match args[0].clone() {
Object::String(string_obj) => Ok(Integer {
value: string_obj.value.len() as i64,
value: string_obj.value().len() as i64,
}
.into()),
Object::Array(array) => Ok(Integer {
Expand Down
12 changes: 11 additions & 1 deletion src/object/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,17 @@ use std::any::Any;
use std::fmt::{Display, Formatter};
#[derive(Debug, Clone, PartialOrd, PartialEq, Eq, Ord, Hash)]
pub struct StringObj {
pub value: String,
value: String,
}

impl StringObj {
pub fn new(value: String) -> Self {
Self { value }
}

pub fn value(&self) -> &String {
&self.value
}
}

impl Display for StringObj {
Expand Down
12 changes: 3 additions & 9 deletions src/parser/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1267,13 +1267,9 @@ fn test_parsing_hash_literals_with_expressions() -> anyhow::Result<()> {
}

fn test_hash_map_use() {
let name1 = StringObj {
value: "name".to_string(),
};
let name1 = StringObj::new("name".to_string());

let monkey = StringObj {
value: "Monkey".to_string(),
};
let monkey = StringObj::new("Monkey".to_string());

let mut pairs = BTreeMap::<Object, Object>::new();
pairs.insert(Object::String(name1.clone()), Object::String(monkey));
Expand All @@ -1287,9 +1283,7 @@ fn test_hash_map_use() {

println!("pairs[name1] = {:?}", pairs.get(&Object::String(name1)));

let name2 = StringObj {
value: "name".to_string(),
};
let name2 = StringObj::new("name".to_string());

println!("pairs[name2] = {:?}", pairs.get(&Object::String(name2)));
}
Expand Down

0 comments on commit da97263

Please sign in to comment.