simple_ir_transformer 0.0.4

SITER - SImple Ir TransformER
Documentation
use std::collections::HashMap;
use crate::Value;

pub struct Python<'a> {
    ir: &'a HashMap<String, Value>,
}

impl<'a> Python<'a> {
    pub fn new(ir: &'a HashMap<String, Value>) -> Self {
        Self { ir }
    }

    fn value_to_code(&self, v: &Value) -> String {
        match v {
            Value::Str(s) => {
                // Проверяем, начинается ли строка с @
                if s.starts_with('@') {
                    // Возвращаем имя переменной без символа @
                    s[1..].to_string()
                } else {
                    // Обычная строка
                    format!("'{}'", s.replace('\'', "\\'"))
                }
            },
            Value::Int(i)  => i.to_string(),
            Value::Bool(b) => if *b { "True" } else { "False" }.to_string(),
            Value::Null    => "None".to_string(),
            
            Value::List(items) => {
                let inner: Vec<String> = items.iter()
                    .map(|item| self.value_to_code(item))
                    .collect();
                format!("[{}]", inner.join(", "))
            }
            
            Value::Map(map) => {
                let inner: Vec<String> = map.iter()
                    .map(|(k, v)| format!("'{}': {}", k, self.value_to_code(v)))
                    .collect();
                format!("{{{}}}", inner.join(", "))
            }
        }
    }

    fn process_imports(&self, code: &mut String) {
        if let Some(Value::List(imports)) = self.ir.get("imports") {
            let mut names: Vec<&str> = imports.iter()
                .filter_map(|i| match i {
                    Value::Str(s) => Some(s.as_str()),
                    _ => None,
                })
                .collect();
            names.sort();
            
            for name in &names {
                code.push_str(&format!("import {}\n", name));
            }
            if !names.is_empty() {
                code.push('\n');
            }
        }
    }

    fn process_variables(&self, code: &mut String) {
        let mut var_keys: Vec<&String> = self.ir.keys()
            .filter(|k| k.starts_with("var:"))
            .collect();
        var_keys.sort();
        
        for key in var_keys {
            if let Value::Map(map) = &self.ir[key] {
                if let Some(val) = map.get("value") {
                    let var_name = &key[4..];
                    code.push_str(&format!("{} = {}\n", var_name, self.value_to_code(val)));
                }
            }
        }
    }

    fn process_calls(&self, code: &mut String) {
        let aliases = crate::transformers::replaceable_names::python_aliases();
        
        let mut call_keys: Vec<&String> = self.ir.keys()
            .filter(|k| k.starts_with("call:"))
            .collect();
        call_keys.sort();
        
        for key in call_keys {
            let func_name = &key[5..];
            let aliased_name = aliases.get(func_name).map(|s| s.as_str()).unwrap_or(func_name);
            
            if let Value::Map(params) = &self.ir[key] {
                let args = if let Some(Value::List(args)) = params.get("args") {
                    args.iter()
                        .map(|arg| self.value_to_code(arg))
                        .collect::<Vec<_>>()
                        .join(", ")
                } else {
                    String::new()
                };
                
                code.push_str(&format!("{}({})\n", aliased_name, args));
            }
        }
    }

    pub fn generate(&self) -> String {
        let mut code = String::new();
        
        self.process_imports(&mut code);
        self.process_variables(&mut code);
        
        if !code.is_empty() && !code.ends_with('\n') {
            code.push('\n');
        }
        
        self.process_calls(&mut code);
        
        code
    }
}