Skip to content

Commit

Permalink
Refactor IndexExpression and InfixExpression structs and related code
Browse files Browse the repository at this point in the history
  • Loading branch information
DaviRain-Su committed Oct 10, 2023
1 parent 55ed492 commit 626e463
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 20 deletions.
18 changes: 15 additions & 3 deletions src/ast/expression/index_expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use std::fmt::{Display, Formatter};

#[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub struct IndexExpression {
pub token: Token, // '[' token word
pub left: Box<Expression>,
pub index: Box<Expression>,
token: Token, // '[' token word
left: Box<Expression>,
index: Box<Expression>,
}

impl IndexExpression {
Expand All @@ -21,6 +21,18 @@ impl IndexExpression {
index: Box::new(Expression::IdentifierExpression(Identifier::default())),
}
}

pub fn left(&self) -> &Expression {
&self.left
}

pub fn index(&self) -> &Expression {
&self.index
}

pub fn index_mut(&mut self) -> &mut Box<Expression> {
&mut self.index
}
}

impl NodeInterface for IndexExpression {
Expand Down
11 changes: 11 additions & 0 deletions src/ast/expression/infix_expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,14 @@ impl TryFrom<Expression> for InfixExpression {
}
}
}

impl TryFrom<&Expression> for InfixExpression {
type Error = anyhow::Error;

fn try_from(value: &Expression) -> Result<Self, Self::Error> {
match value {
Expression::InfixExpression(infix_exp) => Ok(infix_exp.clone()),
unknow => Err(Error::UnknownExpression(unknow.to_string()).into()),
}
}
}
4 changes: 2 additions & 2 deletions src/evaluator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ pub fn eval(node: Node, env: &mut Environment) -> anyhow::Result<Object> {
Ok(Array::new(elements.into_iter().collect()).into())
}
Expression::IndexExpression(indx_exp) => {
let left = eval(Node::from(*indx_exp.left.clone()), env)?;
let index = eval(Node::from(*indx_exp.index.clone()), env)?;
let left = eval(Node::from(indx_exp.left().clone()), env)?;
let index = eval(Node::from(indx_exp.index().clone()), env)?;

eval_index_expression(left, index)
}
Expand Down
2 changes: 1 addition & 1 deletion src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ impl Parser {

self.next_token()?;

exp.index = Box::new(self.parse_expression(LOWEST)?);
*exp.index_mut() = Box::new(self.parse_expression(LOWEST)?);

if self.expect_peek(RBRACKET).is_err() {
return Err(Error::CannotFindTokenType {
Expand Down
28 changes: 14 additions & 14 deletions src/parser/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ fn test_parsing_infix_expression() -> anyhow::Result<()> {
}

if !test_infix_expression(
stmt.unwrap().unwrap().expression,
&stmt.unwrap().unwrap().expression,
&*tt.left_value,
tt.operator.clone(),
&*tt.right_value,
Expand Down Expand Up @@ -708,7 +708,7 @@ fn test_literal_expression(exp: Expression, expected: &dyn Interface) -> anyhow:
}

fn test_infix_expression(
exp: Expression,
exp: &Expression,
left: &dyn Interface,
operator: String,
right: &dyn Interface,
Expand Down Expand Up @@ -762,7 +762,7 @@ fn test_if_expression() -> anyhow::Result<()> {
println!("IfExpression Display is = {}", exp);

if !test_infix_expression(
*exp.condition,
&exp.condition,
&"x".to_string(),
"<".into(),
&"y".to_string(),
Expand Down Expand Up @@ -834,7 +834,7 @@ fn test_if_else_expression() -> anyhow::Result<()> {
let exp = IfExpression::try_from(stmt.unwrap().unwrap().expression)?;

if !test_infix_expression(
*exp.condition,
&exp.condition,
&"x".to_string(),
"<".into(),
&"y".to_string(),
Expand Down Expand Up @@ -927,7 +927,7 @@ fn test_function_literal_parsing() -> anyhow::Result<()> {
}

test_infix_expression(
body_stmt.unwrap().unwrap().expression,
&body_stmt.unwrap().unwrap().expression,
&"x".to_string(),
"+".into(),
&"y".to_string(),
Expand Down Expand Up @@ -1012,8 +1012,8 @@ fn test_call_expression_parsing() -> anyhow::Result<()> {
}

test_literal_expression(exp.arguments()[0].clone(), &1)?;
test_infix_expression(exp.arguments()[1].clone(), &2, "*".into(), &3)?;
test_infix_expression(exp.arguments()[2].clone(), &4, "+".into(), &5)?;
test_infix_expression(&exp.arguments()[1].clone(), &2, "*".into(), &3)?;
test_infix_expression(&exp.arguments()[2].clone(), &4, "+".into(), &5)?;

Ok(())
}
Expand Down Expand Up @@ -1118,8 +1118,8 @@ fn test_parsing_array_literals() -> anyhow::Result<()> {
}

test_integer_literal(array.elements()[0].clone(), 1)?;
test_infix_expression(array.elements()[1].clone(), &2, "*".to_string(), &2)?;
test_infix_expression(array.elements()[2].clone(), &3, "+".to_string(), &3)?;
test_infix_expression(&array.elements()[1], &2, "*".to_string(), &2)?;
test_infix_expression(&array.elements()[2], &3, "+".to_string(), &3)?;

Ok(())
}
Expand All @@ -1139,11 +1139,11 @@ fn test_parsing_index_expression() -> anyhow::Result<()> {
println!("test_test_parsing_index_expression: Stmt = {:#?}", stmt);
let index_exp = IndexExpression::try_from(stmt.unwrap().unwrap().expression)?;

if !test_identifier(*index_exp.left.clone(), "myArray".to_string())? {
if !test_identifier(index_exp.left().clone(), "myArray".to_string())? {
eprintln!("test identifier error");
}

if !test_infix_expression(*index_exp.index.clone(), &1, "+".to_string(), &1)? {
if !test_infix_expression(index_exp.index(), &1, "+".to_string(), &1)? {
eprintln!("test infix expression error");
}

Expand Down Expand Up @@ -1219,7 +1219,7 @@ fn test_parsing_hash_literals_with_expressions() -> anyhow::Result<()> {

impl FuncCall for A {
fn func_call(&self, e: Expression) -> anyhow::Result<()> {
let ret = test_infix_expression(e, &0, "+".to_string(), &1)?;
let ret = test_infix_expression(&e, &0, "+".to_string(), &1)?;
if !ret {
eprintln!("test_infix_expression error")
}
Expand All @@ -1231,7 +1231,7 @@ fn test_parsing_hash_literals_with_expressions() -> anyhow::Result<()> {

impl FuncCall for B {
fn func_call(&self, e: Expression) -> anyhow::Result<()> {
let ret = test_infix_expression(e, &10, "-".to_string(), &8)?;
let ret = test_infix_expression(&e, &10, "-".to_string(), &8)?;
if !ret {
eprintln!("test_infix_expression error")
}
Expand All @@ -1243,7 +1243,7 @@ fn test_parsing_hash_literals_with_expressions() -> anyhow::Result<()> {

impl FuncCall for C {
fn func_call(&self, e: Expression) -> anyhow::Result<()> {
let ret = test_infix_expression(e, &15, "/".to_string(), &5)?;
let ret = test_infix_expression(&e, &15, "/".to_string(), &5)?;
if !ret {
eprintln!("test_infix_expression error")
}
Expand Down

0 comments on commit 626e463

Please sign in to comment.