use crate::*;
use crate::smtlib::*;
use formally::io::{print::Print, print::RenderTarget};
use formally::support::*;
use std::{io, io::Write, sync::RwLock};
pub struct SMTLibEmitter {
write: RwLock<Box<dyn RenderTarget + Send + Sync>>,
}
impl SMTLibEmitter {
pub fn new() -> SMTLibEmitter {
SMTLibEmitter {
write: RwLock::new(Box::new(io::stderr())),
}
}
pub fn writing_to(self, write: impl 'static + RenderTarget + Send + Sync) -> SMTLibEmitter {
SMTLibEmitter {
write: RwLock::new(Box::new(write)),
}
}
}
impl Default for SMTLibEmitter {
fn default() -> Self {
SMTLibEmitter::new()
}
}
impl Emitter for SMTLibEmitter {
fn emit(&self, level: Level, diag: Diagnostic) {
let mut msg = "error:".to_string();
if level != Level::Error {
msg.push_str(&format!("{level}:"));
}
if let Some(span) = diag.span {
msg.push_str(&format!("{span}:"));
}
msg.push(' ');
msg.push_str(&diag.msg);
let error = ast::Response::Error(ast::StringLiteral {
value: msg,
span: None,
});
error.print(&mut **self.write.write().unwrap()).unwrap();
writeln!(&mut *self.write.write().unwrap()).unwrap();
}
fn note(&self, _kind: NoteKind, note: Diagnostic) {
let mut msg = "note:".to_string();
if let Some(span) = note.span {
msg.push_str(&format!("{span}:"));
}
msg.push(' ');
msg.push_str(¬e.msg);
let error = ast::Response::Error(ast::StringLiteral {
value: msg,
span: None,
});
error.print(&mut **self.write.write().unwrap()).unwrap();
writeln!(&mut *self.write.write().unwrap()).unwrap();
}
}