From d4c2b030ecde138c9be37b31ea2205f81cccfff9 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 5 Sep 2026 01:10:35 +0000 Subject: [PATCH 1/2] Allow digits in identifiers after the first character Identifiers required every character to be alphabetic or '_', rejecting common names like x1, arg2, or sha256. The first character still must be alphabetic/'_' so identifiers don't collide with integer literals. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01JxN4ZH5BakVkGVZFY5tbPk --- src/lexical_analysis/mod.rs | 15 +++++++-- src/tests/identifier_expression/mod.rs | 3 +- ...tifier_expression_case_16_environment.snap | 17 ++++++++++ ...ntifier_expression_case_16_evaluation.snap | 7 ++++ ...r_expression_case_16_lexical_analysis.snap | 31 +++++++++++++++++ ...er_expression_case_16_syntax_analysis.snap | 33 +++++++++++++++++++ 6 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 src/tests/identifier_expression/snapshots/monkey_interpreter__tests__identifier_expression__test_identifier_expression_case_16_environment.snap create mode 100644 src/tests/identifier_expression/snapshots/monkey_interpreter__tests__identifier_expression__test_identifier_expression_case_16_evaluation.snap create mode 100644 src/tests/identifier_expression/snapshots/monkey_interpreter__tests__identifier_expression__test_identifier_expression_case_16_lexical_analysis.snap create mode 100644 src/tests/identifier_expression/snapshots/monkey_interpreter__tests__identifier_expression__test_identifier_expression_case_16_syntax_analysis.snap diff --git a/src/lexical_analysis/mod.rs b/src/lexical_analysis/mod.rs index c2b223ac..a644f742 100644 --- a/src/lexical_analysis/mod.rs +++ b/src/lexical_analysis/mod.rs @@ -187,9 +187,20 @@ fn parse_identifier(parsing: &str) -> Option { } fn is_valid_identifier(verifying: &str) -> bool { - verifying.chars().all(is_valid_identifier_character) + let mut characters = verifying.chars(); + + let starts_valid = match characters.next() { + Some(character) => is_valid_identifier_start_character(character), + None => false, + }; + + starts_valid && characters.all(is_valid_identifier_character) } -fn is_valid_identifier_character(character: char) -> bool { +fn is_valid_identifier_start_character(character: char) -> bool { character.is_alphabetic() || character == '_' } + +fn is_valid_identifier_character(character: char) -> bool { + is_valid_identifier_start_character(character) || character.is_ascii_digit() +} diff --git a/src/tests/identifier_expression/mod.rs b/src/tests/identifier_expression/mod.rs index bd3e6c37..35ffc0db 100644 --- a/src/tests/identifier_expression/mod.rs +++ b/src/tests/identifier_expression/mod.rs @@ -42,7 +42,8 @@ use super::*; case( "let is_file = FALSE; let is_directory = !is_file;\nis_directory", "identifier_expression_case_15" - ) + ), + case("let x1 = 5;\nlet arg2 = 10;\nx1 + arg2", "identifier_expression_case_16") )] fn identifier_expression_cases(code: &str, snapshot_name: &str) {} diff --git a/src/tests/identifier_expression/snapshots/monkey_interpreter__tests__identifier_expression__test_identifier_expression_case_16_environment.snap b/src/tests/identifier_expression/snapshots/monkey_interpreter__tests__identifier_expression__test_identifier_expression_case_16_environment.snap new file mode 100644 index 00000000..91bf3d88 --- /dev/null +++ b/src/tests/identifier_expression/snapshots/monkey_interpreter__tests__identifier_expression__test_identifier_expression_case_16_environment.snap @@ -0,0 +1,17 @@ +--- +source: src/tests/identifier_expression/mod.rs +expression: evaluator +--- +Evaluator { + environment: Environment { + variables: { + "arg2": Integer { + value: 10, + }, + "x1": Integer { + value: 5, + }, + }, + sub_environment: None, + }, +} diff --git a/src/tests/identifier_expression/snapshots/monkey_interpreter__tests__identifier_expression__test_identifier_expression_case_16_evaluation.snap b/src/tests/identifier_expression/snapshots/monkey_interpreter__tests__identifier_expression__test_identifier_expression_case_16_evaluation.snap new file mode 100644 index 00000000..8b824dbc --- /dev/null +++ b/src/tests/identifier_expression/snapshots/monkey_interpreter__tests__identifier_expression__test_identifier_expression_case_16_evaluation.snap @@ -0,0 +1,7 @@ +--- +source: src/tests/identifier_expression/mod.rs +expression: evaluation +--- +Integer { + value: 15, +} diff --git a/src/tests/identifier_expression/snapshots/monkey_interpreter__tests__identifier_expression__test_identifier_expression_case_16_lexical_analysis.snap b/src/tests/identifier_expression/snapshots/monkey_interpreter__tests__identifier_expression__test_identifier_expression_case_16_lexical_analysis.snap new file mode 100644 index 00000000..b9abd24d --- /dev/null +++ b/src/tests/identifier_expression/snapshots/monkey_interpreter__tests__identifier_expression__test_identifier_expression_case_16_lexical_analysis.snap @@ -0,0 +1,31 @@ +--- +source: src/tests/identifier_expression/mod.rs +expression: tokens +--- +[ + Let, + Identifier { + literal: "x1", + }, + Assign, + Integer { + literal: 5, + }, + SemiColon, + Let, + Identifier { + literal: "arg2", + }, + Assign, + Integer { + literal: 10, + }, + SemiColon, + Identifier { + literal: "x1", + }, + Plus, + Identifier { + literal: "arg2", + }, +] diff --git a/src/tests/identifier_expression/snapshots/monkey_interpreter__tests__identifier_expression__test_identifier_expression_case_16_syntax_analysis.snap b/src/tests/identifier_expression/snapshots/monkey_interpreter__tests__identifier_expression__test_identifier_expression_case_16_syntax_analysis.snap new file mode 100644 index 00000000..df6b14cd --- /dev/null +++ b/src/tests/identifier_expression/snapshots/monkey_interpreter__tests__identifier_expression__test_identifier_expression_case_16_syntax_analysis.snap @@ -0,0 +1,33 @@ +--- +source: src/tests/identifier_expression/mod.rs +expression: abstract_syntax_tree +--- +[ + Statement { + statement: Let { + identifier: "x1", + expression: Integer { + literal: 5, + }, + }, + }, + Statement { + statement: Let { + identifier: "arg2", + expression: Integer { + literal: 10, + }, + }, + }, + Expression { + expression: Infix { + left_hand: Identifier { + identifier: "x1", + }, + operator: Plus, + right_hand: Identifier { + identifier: "arg2", + }, + }, + }, +] From daa7f6197e9a62da14185508cdf193d4b685a005 Mon Sep 17 00:00:00 2001 From: DeveloperC Date: Sat, 5 Sep 2026 02:27:56 +0100 Subject: [PATCH 2/2] BUILD: WORKING COMMIT - DELETE --- src/tests/identifier_expression/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tests/identifier_expression/mod.rs b/src/tests/identifier_expression/mod.rs index 35ffc0db..7b34807d 100644 --- a/src/tests/identifier_expression/mod.rs +++ b/src/tests/identifier_expression/mod.rs @@ -43,7 +43,10 @@ use super::*; "let is_file = FALSE; let is_directory = !is_file;\nis_directory", "identifier_expression_case_15" ), - case("let x1 = 5;\nlet arg2 = 10;\nx1 + arg2", "identifier_expression_case_16") + case( + "let x1 = 5;\nlet arg2 = 10;\nx1 + arg2", + "identifier_expression_case_16" + ) )] fn identifier_expression_cases(code: &str, snapshot_name: &str) {}