simple_ir_transformer 0.0.4

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

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

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

    fn value_to_code(v: &Value) -> String {
        match v {
            Value::Str(s)  => format!("\"{}\"", s.replace('"', "\\\"")),
            Value::Int(i)  => i.to_string(),
            Value::Bool(b) => if *b { "true" } else { "false" }.to_string(),
            Value::Null    => "nil".to_string(),
            
            Value::List(items) => {
                let inner: Vec<String> = items.iter()
                    .map(Self::value_to_code)
                    .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!("local {} = require('{}')\n", name, 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!("local {} = {}\n", var_name, Self::value_to_code(val)));
                }
            }
        }
    }

    fn process_calls(&self, code: &mut String) {
        let aliases = crate::transformers::replaceable_names::lua_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(Self::value_to_code)
                        .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
    }
}