mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 20:28:02 +00:00
Offer a way to print mono IR in uitest
This commit is contained in:
parent
191d8a7408
commit
53af6ed4eb
6 changed files with 146 additions and 4 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -5084,8 +5084,12 @@ dependencies = [
|
|||
"pretty_assertions",
|
||||
"regex",
|
||||
"roc_builtins",
|
||||
"roc_collections",
|
||||
"roc_derive",
|
||||
"roc_load",
|
||||
"roc_module",
|
||||
"roc_mono",
|
||||
"roc_packaging",
|
||||
"roc_parse",
|
||||
"roc_problem",
|
||||
"roc_reporting",
|
||||
|
|
|
@ -373,9 +373,6 @@ pub fn infer_queries(src: &str, options: InferOptions) -> Result<InferredProgram
|
|||
|
||||
let line_info = LineInfo::new(&src);
|
||||
let queries = parse_queries(&src, &line_info);
|
||||
if queries.is_empty() {
|
||||
return Err("No queries provided!".into());
|
||||
}
|
||||
|
||||
let mut inferred_queries = Vec::with_capacity(queries.len());
|
||||
let exposed_by_module = ExposedByModule::default();
|
||||
|
|
|
@ -14,8 +14,12 @@ harness = false
|
|||
|
||||
[dev-dependencies]
|
||||
roc_builtins = { path = "../builtins" }
|
||||
roc_collections = { path = "../collections" }
|
||||
roc_derive = { path = "../derive", features = ["debug-derived-symbols"] }
|
||||
roc_load = { path = "../load" }
|
||||
roc_packaging = { path = "../../packaging" }
|
||||
roc_module = { path = "../module", features = ["debug-symbols"] }
|
||||
roc_mono = { path = "../mono" }
|
||||
roc_parse = { path = "../parse" }
|
||||
roc_problem = { path = "../problem" }
|
||||
roc_reporting = { path = "../../reporting" }
|
||||
|
|
116
crates/compiler/uitest/src/mono.rs
Normal file
116
crates/compiler/uitest/src/mono.rs
Normal file
|
@ -0,0 +1,116 @@
|
|||
use std::io;
|
||||
|
||||
use bumpalo::Bump;
|
||||
use roc_collections::MutMap;
|
||||
use roc_load::{ExecutionMode, LoadConfig, LoadMonomorphizedError, Threading};
|
||||
use roc_module::symbol::{Interns, Symbol};
|
||||
use roc_mono::{
|
||||
ir::{Proc, ProcLayout},
|
||||
layout::STLayoutInterner,
|
||||
};
|
||||
|
||||
pub fn write_compiled_ir(writer: &mut impl io::Write, module_source: &str) -> io::Result<()> {
|
||||
use roc_packaging::cache::RocCacheDir;
|
||||
use std::path::PathBuf;
|
||||
|
||||
let exec_mode = ExecutionMode::Executable;
|
||||
|
||||
let arena = &Bump::new();
|
||||
|
||||
let filename = PathBuf::from("Test.roc");
|
||||
let src_dir = PathBuf::from("fake/test/path");
|
||||
|
||||
let load_config = LoadConfig {
|
||||
target_info: roc_target::TargetInfo::default_x86_64(),
|
||||
threading: Threading::Single,
|
||||
render: roc_reporting::report::RenderTarget::Generic,
|
||||
palette: roc_reporting::report::DEFAULT_PALETTE,
|
||||
exec_mode,
|
||||
};
|
||||
let loaded = roc_load::load_and_monomorphize_from_str(
|
||||
arena,
|
||||
filename,
|
||||
module_source,
|
||||
src_dir,
|
||||
RocCacheDir::Disallowed,
|
||||
load_config,
|
||||
);
|
||||
|
||||
let loaded = match loaded {
|
||||
Ok(x) => x,
|
||||
Err(LoadMonomorphizedError::LoadingProblem(roc_load::LoadingProblem::FormattedReport(
|
||||
report,
|
||||
))) => {
|
||||
println!("{}", report);
|
||||
panic!();
|
||||
}
|
||||
Err(e) => panic!("{:?}", e),
|
||||
};
|
||||
|
||||
use roc_load::MonomorphizedModule;
|
||||
let MonomorphizedModule {
|
||||
procedures,
|
||||
exposed_to_host,
|
||||
mut layout_interner,
|
||||
interns,
|
||||
..
|
||||
} = loaded;
|
||||
|
||||
let main_fn_symbol = exposed_to_host.top_level_values.keys().copied().next();
|
||||
|
||||
check_procedures(arena, &interns, &mut layout_interner, &procedures);
|
||||
|
||||
write_procedures(writer, layout_interner, procedures, main_fn_symbol)
|
||||
}
|
||||
|
||||
fn check_procedures<'a>(
|
||||
arena: &'a Bump,
|
||||
interns: &Interns,
|
||||
interner: &mut STLayoutInterner<'a>,
|
||||
procedures: &MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
|
||||
) {
|
||||
use roc_mono::debug::{check_procs, format_problems};
|
||||
let problems = check_procs(arena, interner, procedures);
|
||||
if problems.is_empty() {
|
||||
return;
|
||||
}
|
||||
let formatted = format_problems(interns, interner, problems);
|
||||
panic!("IR problems found:\n{formatted}");
|
||||
}
|
||||
|
||||
fn write_procedures<'a>(
|
||||
writer: &mut impl io::Write,
|
||||
interner: STLayoutInterner<'a>,
|
||||
procedures: MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
|
||||
opt_main_fn_symbol: Option<Symbol>,
|
||||
) -> io::Result<()> {
|
||||
let mut procs_strings = procedures
|
||||
.values()
|
||||
.map(|proc| proc.to_pretty(&interner, 200, false))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let opt_main_fn = opt_main_fn_symbol.map(|main_fn_symbol| {
|
||||
let index = procedures
|
||||
.keys()
|
||||
.position(|(s, _)| *s == main_fn_symbol)
|
||||
.unwrap();
|
||||
procs_strings.swap_remove(index)
|
||||
});
|
||||
|
||||
procs_strings.sort();
|
||||
|
||||
if let Some(main_fn) = opt_main_fn {
|
||||
procs_strings.push(main_fn);
|
||||
}
|
||||
|
||||
let mut procs = procs_strings.iter().peekable();
|
||||
while let Some(proc) = procs.next() {
|
||||
if procs.peek().is_some() {
|
||||
writeln!(writer, "{}", proc)?;
|
||||
} else {
|
||||
write!(writer, "{}", proc)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -13,6 +13,8 @@ use test_solve_helpers::{
|
|||
infer_queries, Elaboration, InferOptions, InferredProgram, InferredQuery, MUTLILINE_MARKER,
|
||||
};
|
||||
|
||||
mod mono;
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let args = Arguments::from_args();
|
||||
|
||||
|
@ -110,6 +112,7 @@ struct TestCase {
|
|||
#[derive(Default)]
|
||||
struct PrintOptions {
|
||||
can_decls: bool,
|
||||
mono: bool,
|
||||
}
|
||||
|
||||
impl TestCase {
|
||||
|
@ -154,6 +157,7 @@ impl TestCase {
|
|||
let opt = infer_opt.name("opt").unwrap().as_str();
|
||||
match opt.trim() {
|
||||
"can_decls" => print_opts.can_decls = true,
|
||||
"mono" => print_opts.mono = true,
|
||||
other => return Err(format!("unknown print option: {other:?}").into()),
|
||||
}
|
||||
}
|
||||
|
@ -197,12 +201,20 @@ fn assemble_query_output(
|
|||
write_source_with_answers(&mut reflow, source, sorted_queries, 0)?;
|
||||
|
||||
// Finish up with any remaining print options we were asked to provide.
|
||||
let PrintOptions { can_decls } = print_options;
|
||||
let PrintOptions { can_decls, mono } = print_options;
|
||||
if can_decls {
|
||||
writeln!(writer, "\n{EMIT_HEADER}can_decls")?;
|
||||
program.write_can_decls(writer)?;
|
||||
}
|
||||
|
||||
if mono {
|
||||
writeln!(writer, "\n{EMIT_HEADER}mono")?;
|
||||
// Unfortunately, with the current setup we must now recompile into the IR.
|
||||
// TODO: extend the data returned by a monomorphized module to include
|
||||
// that of a solved module.
|
||||
mono::write_compiled_ir(writer, source)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# +opt print:mono
|
||||
app "test" provides [main] to "./platform"
|
||||
|
||||
main = ""
|
||||
|
||||
# -emit:mono
|
||||
procedure Test.0 ():
|
||||
let Test.1 : Str = "";
|
||||
ret Test.1;
|
Loading…
Add table
Add a link
Reference in a new issue