Skip to content

Commit 15daf2b

Browse files
committed
feat: evaluator type mismatch error
1 parent 2e1cfdc commit 15daf2b

11 files changed

+88
-47
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rust_monkey_interpreter"
3-
version = "0.12.0"
3+
version = "0.13.0"
44
authors = ["C <[email protected]>"]
55
edition = "2018"
66

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Rust Monkey Interpreter
2-
[![pipeline status](https://img.shields.io/badge/Version-0.12.0-blue)](https://gitlab.com/DeveloperC/rust_monkey_interpreter/commits/master) [![pipeline status](https://gitlab.com/DeveloperC/rust_monkey_interpreter/badges/master/pipeline.svg)](https://gitlab.com/DeveloperC/rust_monkey_interpreter/commits/master) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
2+
[![pipeline status](https://img.shields.io/badge/Version-0.13.0-blue)](https://gitlab.com/DeveloperC/rust_monkey_interpreter/commits/master) [![pipeline status](https://gitlab.com/DeveloperC/rust_monkey_interpreter/badges/master/pipeline.svg)](https://gitlab.com/DeveloperC/rust_monkey_interpreter/commits/master) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
33

44
![The Monkey Programming Language Logo](https://cloud.githubusercontent.com/assets/1013641/22617482/9c60c27c-eb09-11e6-9dfa-b04c7fe498ea.png)
55

src/evaluator/infix/mod.rs

Lines changed: 35 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,55 +4,51 @@ use crate::syntax_analysis::abstract_syntax_tree::syntax_tree_node::*;
44

55
pub fn evaluate(left_hand: Expression, operator_token: Token, right_hand: Expression) -> Object {
66
match crate::evaluator::evaluate_expression(left_hand) {
7-
Object::INTEGER { value } => {
8-
let left_value = value;
7+
Object::INTEGER { value: left_value } => {
98
match crate::evaluator::evaluate_expression(right_hand) {
10-
Object::INTEGER { value } => {
11-
let right_value = value;
12-
match operator_token {
13-
Token::PLUS => Object::INTEGER {
14-
value: left_value + right_value,
15-
},
16-
Token::MINUS => Object::INTEGER {
17-
value: left_value - right_value,
18-
},
19-
Token::MULTIPLY => Object::INTEGER {
20-
value: left_value * right_value,
21-
},
22-
Token::DIVIDE => Object::INTEGER {
23-
value: left_value / right_value,
24-
},
25-
Token::GREATER_THAN => match left_value > right_value {
26-
true => Object::TRUE,
27-
false => Object::FALSE,
28-
},
29-
Token::LESSER_THAN => match left_value < right_value {
30-
true => Object::TRUE,
31-
false => Object::FALSE,
32-
},
33-
Token::EQUALS => match left_value == right_value {
34-
true => Object::TRUE,
35-
false => Object::FALSE,
36-
},
37-
Token::NOT_EQUALS => match left_value != right_value {
38-
true => Object::TRUE,
39-
false => Object::FALSE,
40-
},
41-
_ => Object::NULL,
42-
}
43-
}
44-
_ => Object::NULL,
9+
Object::INTEGER { value: right_value } => match operator_token {
10+
Token::PLUS => Object::INTEGER {
11+
value: left_value + right_value,
12+
},
13+
Token::MINUS => Object::INTEGER {
14+
value: left_value - right_value,
15+
},
16+
Token::MULTIPLY => Object::INTEGER {
17+
value: left_value * right_value,
18+
},
19+
Token::DIVIDE => Object::INTEGER {
20+
value: left_value / right_value,
21+
},
22+
Token::GREATER_THAN => match left_value > right_value {
23+
true => Object::TRUE,
24+
false => Object::FALSE,
25+
},
26+
Token::LESSER_THAN => match left_value < right_value {
27+
true => Object::TRUE,
28+
false => Object::FALSE,
29+
},
30+
Token::EQUALS => match left_value == right_value {
31+
true => Object::TRUE,
32+
false => Object::FALSE,
33+
},
34+
Token::NOT_EQUALS => match left_value != right_value {
35+
true => Object::TRUE,
36+
false => Object::FALSE,
37+
},
38+
_ => Object::NULL,
39+
},
40+
_ => Object::TYPE_MISMATCH,
4541
}
4642
}
4743
Object::TRUE => match crate::evaluator::evaluate_expression(right_hand) {
4844
Object::TRUE => evaluate_same_boolean(operator_token),
4945
Object::FALSE => evaluate_opposite_boolean(operator_token),
50-
_ => Object::NULL,
46+
_ => Object::TYPE_MISMATCH,
5147
},
5248
Object::FALSE => match crate::evaluator::evaluate_expression(right_hand) {
5349
Object::FALSE => evaluate_same_boolean(operator_token),
5450
Object::TRUE => evaluate_opposite_boolean(operator_token),
55-
_ => Object::NULL,
51+
_ => Object::TYPE_MISMATCH,
5652
},
5753
_ => Object::NULL,
5854
}

src/evaluator/infix/tests/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,21 @@ fn test_evaluator_infix_integer_expressions(code: &str, snapshot_name: &str) {
4646
fn test_evaluator_infix_boolean_expressions(code: &str, snapshot_name: &str) {
4747
assert_expected_returned_object!(code, snapshot_name);
4848
}
49+
50+
#[rstest(
51+
code,
52+
snapshot_name,
53+
case("(1 > 2) == 5", "test_evaluator_infix_type_mismatch_expressions_case1"),
54+
case(
55+
"5 + TRUE; 5 + 10;",
56+
"test_evaluator_infix_type_mismatch_expressions_case2"
57+
),
58+
case("FALSE - 10;", "test_evaluator_infix_type_mismatch_expressions_case3"),
59+
case(
60+
"if (10 > 1) { return TRUE + 5; } return 1;",
61+
"test_evaluator_infix_type_mismatch_expressions_case4"
62+
)
63+
)]
64+
fn test_evaluator_infix_type_mismatch_expressions(code: &str, snapshot_name: &str) {
65+
assert_expected_returned_object!(code, snapshot_name);
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
source: src/evaluator/infix/tests/mod.rs
3+
expression: "crate::evaluator::evaluate(crate::syntax_analysis::get_abstract_syntax_tree(crate::lexical_analysis::get_tokens(code.to_string())))"
4+
---
5+
"TYPE_MISMATCH"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
source: src/evaluator/infix/tests/mod.rs
3+
expression: "crate::evaluator::evaluate(crate::syntax_analysis::get_abstract_syntax_tree(crate::lexical_analysis::get_tokens(code.to_string())))"
4+
---
5+
"TYPE_MISMATCH"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
source: src/evaluator/infix/tests/mod.rs
3+
expression: "crate::evaluator::evaluate(crate::syntax_analysis::get_abstract_syntax_tree(crate::lexical_analysis::get_tokens(code.to_string())))"
4+
---
5+
"TYPE_MISMATCH"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
source: src/evaluator/infix/tests/mod.rs
3+
expression: "crate::evaluator::evaluate(crate::syntax_analysis::get_abstract_syntax_tree(crate::lexical_analysis::get_tokens(code.to_string())))"
4+
---
5+
"TYPE_MISMATCH"

src/evaluator/mod.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,13 @@ pub fn evaluate(abstract_syntax_tree: AbstractSyntaxTree) -> Object {
1717
for syntax_tree_node in abstract_syntax_tree.abstract_syntax_tree {
1818
object = evaluate_node(syntax_tree_node);
1919

20-
if let Object::RETURN { value } = object.clone() {
21-
object = *value;
22-
break;
20+
match object.clone() {
21+
Object::RETURN { value } => {
22+
object = *value;
23+
break;
24+
}
25+
Object::TYPE_MISMATCH => break,
26+
_ => {}
2327
}
2428
}
2529

@@ -32,8 +36,9 @@ fn evaluate_block(block: Block) -> Object {
3236
for syntax_tree_node in block.nodes {
3337
object = evaluate_node(syntax_tree_node);
3438

35-
if let Object::RETURN { value: _ } = object.clone() {
36-
break;
39+
match object.clone() {
40+
Object::RETURN { value: _ } | Object::TYPE_MISMATCH => break,
41+
_ => {}
3742
}
3843
}
3944

0 commit comments

Comments
 (0)