Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 6 additions & 9 deletions src/evaluator/environment/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,13 @@ impl Environment {
self.variables.insert(identifier, value);
}

pub(super) fn get<T: AsRef<str>>(&self, identifier: T) -> Object {
pub(super) fn get<T: AsRef<str>>(&self, identifier: T) -> Option<Object> {
match self.variables.get(identifier.as_ref()) {
Some(value) => value.clone(),
None => {
if let Some(sub_environment) = &self.sub_environment {
return sub_environment.get(identifier);
}

Object::Null
}
Some(value) => Some(value.clone()),
None => match &self.sub_environment {
Some(sub_environment) => sub_environment.get(identifier),
None => None,
},
}
}
}
14 changes: 14 additions & 0 deletions src/evaluator/expression/identifier/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use crate::evaluator::Evaluator;
use crate::evaluator::Object;

impl Evaluator {
pub(super) fn evaluate_identifier_expression(
&self,
identifier: String,
) -> anyhow::Result<Object> {
match self.environment.get(&identifier) {
Some(object) => Ok(object),
None => anyhow::bail!("Identifier not found: {}.", identifier),
}
}
}
5 changes: 4 additions & 1 deletion src/evaluator/expression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::syntax_analysis::*;
mod boolean;
mod call;
mod function;
mod identifier;
mod if_expression;
mod infix;
mod integer;
Expand Down Expand Up @@ -33,7 +34,9 @@ impl Evaluator {
consequence,
alternative,
} => self.evaluate_if_expression(*condition, *consequence, *alternative),
Expression::Identifier { identifier } => Ok(self.environment.get(identifier)),
Expression::Identifier { identifier } => {
self.evaluate_identifier_expression(identifier)
}
Expression::Function { parameters, block } => {
self.evaluate_function_expression(parameters, *block)
}
Expand Down
42 changes: 42 additions & 0 deletions src/tests/evaluation_error/identifier_not_found/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use super::*;

#[template]
#[rstest(
code,
snapshot_name,
case("foobar;", "identifier_not_found_case_1"),
case("let is_directory = false;\nis_file", "identifier_not_found_case_2"),
case("let a = 5;\na + b", "identifier_not_found_case_3"),
case(
"let double = fn(x) { x * 2 };\ndoubel(5)",
"identifier_not_found_case_4"
),
case(
"let double = fn(x) { x * multiplier };\ndouble(5)",
"identifier_not_found_case_5"
),
case(
"let identity = fn(x) { x };\nidentity(1);\nx",
"identifier_not_found_case_6"
),
case("if (unknown) { 1 } else { 2 };", "identifier_not_found_case_7"),
case("let a = b;", "identifier_not_found_case_8"),
case("return missing;", "identifier_not_found_case_9"),
case("!undefined_boolean;", "identifier_not_found_case_10")
)]
fn identifier_not_found_cases(code: &str, snapshot_name: &str) {}

#[apply(identifier_not_found_cases)]
fn test_identifier_not_found_lexical_analysis(code: &str, snapshot_name: &str) {
assert_lexical_analysis!(code, snapshot_name);
}

#[apply(identifier_not_found_cases)]
fn test_identifier_not_found_syntax_analysis(code: &str, snapshot_name: &str) {
assert_syntax_analysis!(code, snapshot_name);
}

#[apply(identifier_not_found_cases)]
fn test_identifier_not_found_evaluation_error(code: &str, snapshot_name: &str) {
assert_evaluation_error!(code, snapshot_name);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
source: src/tests/evaluation_error/identifier_not_found/mod.rs
expression: error
---
Err(
"Identifier not found: undefined_boolean.",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
source: src/tests/evaluation_error/identifier_not_found/mod.rs
expression: tokens
---
[
Not,
Identifier {
literal: "undefined_boolean",
},
SemiColon,
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
source: src/tests/evaluation_error/identifier_not_found/mod.rs
expression: abstract_syntax_tree
---
[
Expression {
expression: NotPrefix {
right_hand: Identifier {
identifier: "undefined_boolean",
},
},
},
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
source: src/tests/evaluation_error/identifier_not_found/mod.rs
expression: error
---
Err(
"Identifier not found: foobar.",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
source: src/tests/evaluation_error/identifier_not_found/mod.rs
expression: tokens
---
[
Identifier {
literal: "foobar",
},
SemiColon,
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
source: src/tests/evaluation_error/identifier_not_found/mod.rs
expression: abstract_syntax_tree
---
[
Expression {
expression: Identifier {
identifier: "foobar",
},
},
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
source: src/tests/evaluation_error/identifier_not_found/mod.rs
expression: error
---
Err(
"Identifier not found: is_file.",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
source: src/tests/evaluation_error/identifier_not_found/mod.rs
expression: tokens
---
[
Let,
Identifier {
literal: "is_directory",
},
Assign,
False,
SemiColon,
Identifier {
literal: "is_file",
},
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
source: src/tests/evaluation_error/identifier_not_found/mod.rs
expression: abstract_syntax_tree
---
[
Statement {
statement: Let {
identifier: "is_directory",
expression: Boolean {
literal: false,
},
},
},
Expression {
expression: Identifier {
identifier: "is_file",
},
},
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
source: src/tests/evaluation_error/identifier_not_found/mod.rs
expression: error
---
Err(
"Identifier not found: b.",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
source: src/tests/evaluation_error/identifier_not_found/mod.rs
expression: tokens
---
[
Let,
Identifier {
literal: "a",
},
Assign,
Integer {
literal: 5,
},
SemiColon,
Identifier {
literal: "a",
},
Plus,
Identifier {
literal: "b",
},
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
source: src/tests/evaluation_error/identifier_not_found/mod.rs
expression: abstract_syntax_tree
---
[
Statement {
statement: Let {
identifier: "a",
expression: Integer {
literal: 5,
},
},
},
Expression {
expression: Infix {
left_hand: Identifier {
identifier: "a",
},
operator: Plus,
right_hand: Identifier {
identifier: "b",
},
},
},
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
source: src/tests/evaluation_error/identifier_not_found/mod.rs
expression: error
---
Err(
"Identifier not found: doubel.",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
source: src/tests/evaluation_error/identifier_not_found/mod.rs
expression: tokens
---
[
Let,
Identifier {
literal: "double",
},
Assign,
Function,
OpeningRoundBracket,
Identifier {
literal: "x",
},
ClosingRoundBracket,
OpeningCurlyBracket,
Identifier {
literal: "x",
},
Multiply,
Integer {
literal: 2,
},
ClosingCurlyBracket,
SemiColon,
Identifier {
literal: "doubel",
},
OpeningRoundBracket,
Integer {
literal: 5,
},
ClosingRoundBracket,
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
source: src/tests/evaluation_error/identifier_not_found/mod.rs
expression: abstract_syntax_tree
---
[
Statement {
statement: Let {
identifier: "double",
expression: Function {
parameters: [
"x",
],
block: Block {
nodes: [
Expression {
expression: Infix {
left_hand: Identifier {
identifier: "x",
},
operator: Multiply,
right_hand: Integer {
literal: 2,
},
},
},
],
},
},
},
},
Expression {
expression: Call {
function: Identifier {
identifier: "doubel",
},
arguments: [
Integer {
literal: 5,
},
],
},
},
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
source: src/tests/evaluation_error/identifier_not_found/mod.rs
expression: error
---
Err(
"Identifier not found: multiplier.",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
source: src/tests/evaluation_error/identifier_not_found/mod.rs
expression: tokens
---
[
Let,
Identifier {
literal: "double",
},
Assign,
Function,
OpeningRoundBracket,
Identifier {
literal: "x",
},
ClosingRoundBracket,
OpeningCurlyBracket,
Identifier {
literal: "x",
},
Multiply,
Identifier {
literal: "multiplier",
},
ClosingCurlyBracket,
SemiColon,
Identifier {
literal: "double",
},
OpeningRoundBracket,
Integer {
literal: 5,
},
ClosingRoundBracket,
]
Loading
Loading