Compile HLL source to the final assembled output and export it as an ELF image ready for qemu-riscv64. Uses two-stage compilation: compile stdlib and user code independently, then assemble and link through the pipeline.
(source: &str)
| 157 | .compile(source) |
| 158 | .unwrap_or_else(|e| panic!("HLL compilation failed: {e}")); |
| 159 | let (_, user_tokens) = pipeline.compile_ir_to_assembly_with_tokens(&user_result.ir_program); |
| 160 | let user_obj = pipeline |
| 161 | .assemble(&user_tokens) |
| 162 | .unwrap_or_else(|e| panic!("user assembly failed: {e}")); |
| 163 | |
| 164 | let mut modules: Vec<(&str, &AssembledOutput)> = |
| 165 | stdlib_objs.iter().map(|(n, o)| (n.as_str(), o)).collect(); |
| 166 | modules.push(("user", &user_obj)); |
| 167 | let assembled = pipeline |
| 168 | .link_assembled_objects(&modules) |
| 169 | .unwrap_or_else(|e| panic!("link failed: {e}")); |
| 170 | assembled.to_elf(ELF_LOAD_BASE) |
| 171 | } |
| 172 | |
| 173 | // `C:\Users\foo\bar.elf` -> `/mnt/c/Users/foo/bar.elf` |
| 174 | #[cfg(target_os = "windows")] |
| 175 | fn win_path_to_wsl(path: &std::path::Path) -> String { |
| 176 | let s = path.to_string_lossy(); |
| 177 | // Expect "X:\rest\of\path" |
| 178 | let (drive, rest) = if s.len() >= 3 && s.as_bytes()[1] == b':' { |
| 179 | let drive = s[..1].to_lowercase(); |
| 180 | let rest = s[2..].replace('\\', "/"); |
| 181 | (drive, rest) |
| 182 | } else { |
| 183 | // Not a drive-rooted path - best-effort conversion |
| 184 | return s.replace('\\', "/"); |
| 185 | }; |
no test coverage detected