use std::collections::HashMap;
use crate::Value;
pub struct Python<'a> {
pub ir_hm: &'a HashMap<String, Value>,
}
impl<'a> Python<'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(), Value::Null => "None".to_string(),
Value::List(items) => {
let inner = items
.iter()
.map(Self::format_value)
.collect::<Vec<_>>()
.join(", ");
format!("[{}]", inner)
}
Value::Map(map) => {
let inner = map
.iter()
.map(|(k, v)| format!("\"{}\": {}", k, Self::format_value(v)))
.collect::<Vec<_>>()
.join(", ");
format!("{{{}}}", inner)
}
}
}
pub fn transpile(&self) -> String {
let mut pycode = 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 {
pycode.push_str(&format!("import {}\n", name));
}
pycode.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:");
pycode.push_str(&format!("{} = {}\n", name, Self::format_value(val)));
}
}
}
pycode
}
}