simple_ir_transformer 0.0.1

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

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

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

    fn format_value(v: &Value) -> String {
        match v {
            Value::Str(s)  => format!("\"{}\"", s),
            Value::Int(i)  => i.to_string(),
            Value::Bool(b) => if *b { "true" } else { "false" }.to_string(), // Lua: строчные
            Value::Null    => "nil".to_string(),                              // Lua: nil, не null/None

            Value::List(items) => {
                let inner = items
                    .iter()
                    .map(Self::format_value)
                    .collect::<Vec<_>>()
                    .join(", ");
                format!("{{{}}}", inner) // Lua: списки это таблицы {1, 2, 3}
            }

            Value::Map(map) => {
                let inner = map
                    .iter()
                    .map(|(k, v)| format!("{} = {}", k, Self::format_value(v)))
                    .collect::<Vec<_>>()
                    .join(", ");
                format!("{{{}}}", inner) // Lua: {key = value}
            }
        }
    }

    pub fn transpile(&self) -> String {
        let mut lua_code = String::new();

        // импорты — сортировка для детерминированного вывода
        if let Some(Value::List(imports)) = self.ir_hm.get("imports") {
            let mut names: Vec<&str> = imports
                .iter()
                .filter_map(|i| if let Value::Str(s) = i { Some(s.as_str()) } else { None })
                .collect();
            names.sort();
            for name in names {
                lua_code.push_str(&format!("local {} = require(\"{}\")\n", name, name));
            }
            lua_code.push('\n');
        }

        // переменные
        let mut var_keys: Vec<&String> = self.ir_hm
            .keys()
            .filter(|k| k.starts_with("var:"))
            .collect();
        var_keys.sort();

        for key in var_keys {
            if let Value::Map(map) = &self.ir_hm[key] {
                if let Some(val) = map.get("value") {
                    let name = key.trim_start_matches("var:");
                    lua_code.push_str(&format!("local {} = {}\n", name, Self::format_value(val)));
                }
            }
        }

        lua_code
    }
}