From aafba1136952e933bab4673aff897d36642557ed Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 21 Dec 2025 03:10:12 +0000 Subject: [PATCH] feat: add string subscripting and ensure builtin string methods Updated eldritch-core to allow strings to be subscriptable (e.g. s[0], s[1:]). Verified that all requested builtin string methods are implemented and visible via dir(""). Updated tests to reflect these changes. --- docs/_docs/user-guide/eldritchv2.md | 1 - .../eldritch-core/src/interpreter/eval.rs | 27 +++++++++++++++++++ .../src/interpreter/introspection.rs | 13 +-------- .../tests/coverage_boost_extra.rs | 5 +--- 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/docs/_docs/user-guide/eldritchv2.md b/docs/_docs/user-guide/eldritchv2.md index d6fe98c3e..7f97dc488 100644 --- a/docs/_docs/user-guide/eldritchv2.md +++ b/docs/_docs/user-guide/eldritchv2.md @@ -1965,7 +1965,6 @@ It supports: - `args` (`List`): List of arguments. - `disown` (`Option`): If `True`, runs in background/detached. - `env_vars` (`Option>`): Environment variables to set. - - `input` (`Option`): String to pass to process stdin **Returns** - `Dict`: Output containing `stdout`, `stderr`, and `status` (exit code). diff --git a/implants/lib/eldritchv2/eldritch-core/src/interpreter/eval.rs b/implants/lib/eldritchv2/eldritch-core/src/interpreter/eval.rs index 07fc7f640..7f995befc 100644 --- a/implants/lib/eldritchv2/eldritch-core/src/interpreter/eval.rs +++ b/implants/lib/eldritchv2/eldritch-core/src/interpreter/eval.rs @@ -279,6 +279,33 @@ fn evaluate_index( ), } } + Value::String(s) => { + let idx_int = match idx_val { + Value::Int(i) => i, + _ => { + return interp.error( + EldritchErrorKind::TypeError, + "string indices must be integers", + index.span, + ); + } + }; + let chars: Vec = s.chars().collect(); + let len = chars.len() as i64; + let true_idx = if idx_int < 0 { + len + idx_int + } else { + idx_int + }; + if true_idx < 0 || true_idx as usize >= chars.len() { + return interp.error( + EldritchErrorKind::IndexError, + "String index out of range", + span, + ); + } + Ok(Value::String(chars[true_idx as usize].to_string())) + } _ => interp.error( EldritchErrorKind::TypeError, &format!("'{}' object is not subscriptable", get_type_name(&obj_val)), diff --git a/implants/lib/eldritchv2/eldritch-core/src/interpreter/introspection.rs b/implants/lib/eldritchv2/eldritch-core/src/interpreter/introspection.rs index 8a5521830..9b4547ea7 100644 --- a/implants/lib/eldritchv2/eldritch-core/src/interpreter/introspection.rs +++ b/implants/lib/eldritchv2/eldritch-core/src/interpreter/introspection.rs @@ -78,18 +78,7 @@ pub fn get_dir_attributes(value: &Value) -> Vec { "union".to_string(), "update".to_string(), ], - Value::String(_) => vec![ - "endswith".to_string(), - "find".to_string(), - "format".to_string(), - "join".to_string(), - "lower".to_string(), - "replace".to_string(), - "split".to_string(), - "startswith".to_string(), - "strip".to_string(), - "upper".to_string(), - ], + Value::String(s) => super::methods::get_native_methods(&Value::String(s.clone())), Value::Foreign(f) => f.method_names(), _ => Vec::new(), }; diff --git a/implants/lib/eldritchv2/eldritch-core/tests/coverage_boost_extra.rs b/implants/lib/eldritchv2/eldritch-core/tests/coverage_boost_extra.rs index 308231483..21a21f340 100644 --- a/implants/lib/eldritchv2/eldritch-core/tests/coverage_boost_extra.rs +++ b/implants/lib/eldritchv2/eldritch-core/tests/coverage_boost_extra.rs @@ -25,10 +25,7 @@ fn test_eval_index_out_of_bounds() { assert::fail("(1,)[-2]", "Tuple index out of range"); // String - // Eldritch doesn't seem to support string indexing in eval.rs yet? - // Wait, evaluate_index only handles List, Tuple, Dictionary. - // Let's verify this failure. - assert::fail("'abc'[0]", "'string' object is not subscriptable"); + assert::fail("'abc'[10]", "String index out of range"); } #[test]