Files
2026-05-16 19:03:49 +03:00

86 lines
2.6 KiB
Rust

use crate::keywords::{
has_export, is_function_end, is_function_start, is_procedure_end, is_procedure_start,
};
use crate::models::{ParsedProcedure, SourceRange};
pub fn extract_procedures(source: &str) -> Vec<ParsedProcedure> {
let mut result = Vec::new();
let mut current_index: Option<usize> = None;
for (index, line) in source.lines().enumerate() {
let line_no = index + 1;
if is_procedure_start(line) || is_function_start(line) {
let is_function = is_function_start(line);
let name = extract_routine_name(line, is_function);
result.push(ParsedProcedure {
name,
export: has_export(line),
is_function,
parameters: extract_parameters(line),
source_range: SourceRange {
line_start: line_no,
line_end: line_no,
column_start: 1,
column_end: line.len() + 1,
},
});
current_index = Some(result.len() - 1);
} else if routine_ended(line) {
if let Some(procedure_index) = current_index.take() {
result[procedure_index].source_range.line_end = line_no;
result[procedure_index].source_range.column_end = line.len() + 1;
}
}
}
result
}
pub fn routine_ended(line: &str) -> bool {
is_procedure_end(line) || is_function_end(line)
}
pub fn extract_name_from_header(line: &str) -> String {
line.split_whitespace()
.nth(1)
.unwrap_or("")
.split('(')
.next()
.unwrap_or("")
.to_string()
}
fn extract_routine_name(line: &str, is_function: bool) -> String {
let trimmed = line.trim();
let prefixes = if is_function {
vec!["Функция", "Function"]
} else {
vec!["Процедура", "Procedure"]
};
for prefix in prefixes {
if trimmed.to_lowercase().starts_with(&prefix.to_lowercase()) {
return trimmed[prefix.len()..]
.trim()
.split('(')
.next()
.unwrap_or("")
.trim()
.to_string();
}
}
String::new()
}
fn extract_parameters(line: &str) -> Vec<String> {
let Some(start) = line.find('(') else {
return Vec::new();
};
let Some(end) = line[start + 1..].find(')') else {
return Vec::new();
};
let params = &line[start + 1..start + 1 + end];
params
.split(',')
.map(|p| p.trim().to_string())
.filter(|p| !p.is_empty())
.collect()
}