|
| 1 | +use crate::builtin_function::utils::{param_to_datatype, returns}; |
| 2 | +use crate::common::data_type::DataType; |
| 3 | +use crate::common::errors::{ChapError, Result}; |
| 4 | +use crate::{common::executable::ExecutableLine, runtime::Runtime}; |
| 5 | + |
| 6 | +pub fn char_at(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { |
| 7 | + let p1 = param_to_datatype(runtime, executable.params.first(), executable.line_number)?; |
| 8 | + let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; |
| 9 | + |
| 10 | + let (string_value, index) = match (&p1, &p2) { |
| 11 | + (DataType::String(s), DataType::Int(i)) => (s, *i), |
| 12 | + _ => { |
| 13 | + return Err(ChapError::runtime_with_msg( |
| 14 | + executable.line_number, |
| 15 | + format!( |
| 16 | + "{} function requires a string as first parameter and an integer as second parameter", |
| 17 | + executable.function_name |
| 18 | + ), |
| 19 | + )); |
| 20 | + } |
| 21 | + }; |
| 22 | + |
| 23 | + // Chap uses 1-based indexing, so index must be >= 1 |
| 24 | + if index < 1 { |
| 25 | + return Err(ChapError::runtime_with_msg( |
| 26 | + executable.line_number, |
| 27 | + format!( |
| 28 | + "Index {} is invalid. Index must be 1 or greater (1-based indexing)", |
| 29 | + index |
| 30 | + ), |
| 31 | + )); |
| 32 | + } |
| 33 | + |
| 34 | + let index_usize = index as usize; |
| 35 | + |
| 36 | + // Check if index is within bounds (convert to 0-based for length check) |
| 37 | + if index_usize > string_value.len() { |
| 38 | + return Err(ChapError::runtime_with_msg( |
| 39 | + executable.line_number, |
| 40 | + format!( |
| 41 | + "Index {} is out of bounds for string of length {}", |
| 42 | + index, |
| 43 | + string_value.len() |
| 44 | + ), |
| 45 | + )); |
| 46 | + } |
| 47 | + |
| 48 | + // Get the character at the specified index (convert to 0-based indexing) |
| 49 | + let chars: Vec<char> = string_value.chars().collect(); |
| 50 | + let result_char = chars[index_usize - 1]; |
| 51 | + let result = DataType::String(result_char.to_string()); |
| 52 | + |
| 53 | + returns(runtime, executable, result) |
| 54 | +} |
0 commit comments