mod backends;
use std::collections::HashMap;
use tinyjson::JsonValue;
pub static VERSION: &str = "1.0.0";
#[derive(Debug, Clone)]
pub enum Value {
Str(String),
Int(i64),
Bool(bool),
List(Vec<Value>),
Map(HashMap<String, Value>),
Null,
}
#[derive(Debug)]
pub enum IRError {
ParseError(String),
InvalidRoot,
UnknownLanguage(String),
}
impl std::fmt::Display for IRError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
IRError::ParseError(e) => write!(f, "Ошибка парсинга JSON: {}", e),
IRError::InvalidRoot => write!(f, "IR должен быть JSON объектом"),
IRError::UnknownLanguage(l) => write!(f, "Неизвестный язык: {}", l),
}
}
}
pub struct IR {
pub ir: String,
}
impl IR {
pub fn new(ir: String) -> Self {
Self { ir }
}
fn convert(v: JsonValue) -> Value {
match v {
JsonValue::String(s) => Value::Str(s),
JsonValue::Number(n) => Value::Int(n as i64),
JsonValue::Boolean(b) => Value::Bool(b),
JsonValue::Array(arr) => {
Value::List(arr.into_iter().map(Self::convert).collect())
}
JsonValue::Object(map) => {
Value::Map(
map.into_iter()
.map(|(k, v)| (k, Self::convert(v)))
.collect()
)
}
JsonValue::Null => Value::Null,
}
}
pub fn transpile(&self, lang: &str) -> Result<String, IRError> {
let jj: JsonValue = self.ir
.parse()
.map_err(|e: tinyjson::JsonParseError| IRError::ParseError(e.to_string()))?;
let obj_map = match jj {
JsonValue::Object(map) => map,
_ => return Err(IRError::InvalidRoot),
};
let converted: HashMap<String, Value> = obj_map
.into_iter()
.map(|(k, v)| (k, Self::convert(v)))
.collect();
match lang {
"Python" => {
Ok(backends::python_backend::Python::new(&converted).transpile())
}
"JavaScript" => {
Ok(backends::js_backend::JS::new(&converted).transpile())
}
"Lua" => {
Ok(backends::lua_backend::Lua::new(&converted).transpile())
}
_ => Err(IRError::UnknownLanguage(lang.to_string())),
}
}
}