///|
fn ir_escape(value : String) -> String {
let builder = StringBuilder()
for character in value {
match character {
'"' => builder.write_string("\\\"")
'\\' => builder.write_string("\\\\")
'\n' => builder.write_string("\\n")
'\r' => builder.write_string("\\r")
'\t' => builder.write_string("\\t")
_ => builder.write_char(character)
}
}
builder.to_string()
}
///|
/// Emit a deterministic, dependency-free JSON representation of the semantic index.
pub fn SemanticIndex::to_ir_json(self : SemanticIndex) -> String {
let builder = StringBuilder()
builder.write_string("{\"modules\":[")
for index, mod in self.modules {
if index > 0 {
builder.write_char(',')
}
builder.write_string("{\"name\":\"")
builder.write_string(ir_escape(mod.name))
builder.write_string("\",\"ports\":[")
for port_index, port in mod.ports {
if port_index > 0 {
builder.write_char(',')
}
builder.write_string("{\"name\":\"")
builder.write_string(ir_escape(port.name))
builder.write_string("\",\"direction\":\"")
builder.write_string(
match port.direction {
@syntax.Input => "input"
@syntax.Output => "output"
@syntax.Inout => "inout"
@syntax.Unspecified => "unspecified"
},
)
builder.write_string("\"}")
}
builder.write_string("],\"signals\":[")
for signal_index, signal in mod.signals {
if signal_index > 0 {
builder.write_char(',')
}
builder.write_string("{\"name\":\"")
builder.write_string(ir_escape(signal.name))
builder.write_string("\",\"width\":")
match signal.width {
Known(width) => builder.write_object(width)
Unknown => builder.write_string("null")
}
builder.write_string(",\"drivers\":")
builder.write_object(signal.drivers.length())
builder.write_char('}')
}
builder.write_string("],\"instances\":[")
for instance_index, instance in mod.instances {
if instance_index > 0 {
builder.write_char(',')
}
builder.write_string("{\"module\":\"")
builder.write_string(ir_escape(instance.module_name))
builder.write_string("\",\"name\":\"")
builder.write_string(ir_escape(instance.instance_name))
builder.write_string("\"}")
}
builder.write_string("]}")
}
builder.write_string("],\"edges\":[")
for index, edge in self.graph.edges() {
if index > 0 {
builder.write_char(',')
}
let (parent, child) = edge
builder.write_string("[\"")
builder.write_string(ir_escape(parent))
builder.write_string("\",\"")
builder.write_string(ir_escape(child))
builder.write_string("\"]")
}
builder.write_string("]}\n")
builder.to_string()
}