| 695 | for (_alias, path) in module_imports { |
| 696 | let resolved = self |
| 697 | .resolve_module_source(&path, source_path.as_deref()) |
| 698 | .map_err(|msg| CompilationError::FreestandingErrors(vec![msg]))? |
| 699 | .ok_or_else(|| { |
| 700 | let key = Self::module_key(&path); |
| 701 | CompilationError::FreestandingErrors(vec![format!( |
| 702 | "cannot resolve import(\"{path}\"): no module named `{key}`" |
| 703 | )]) |
| 704 | })?; |
| 705 | // Stdlib modules are precompiled separately; header-only modules (e.g. `layout`) |
| 706 | // produce no object and reach the importer through the prepended interface. |
| 707 | if resolved.is_stdlib |
| 708 | || !hll_to_ir::imports::defines_code(&resolved.source) |
| 709 | .map_err(|msg| CompilationError::FreestandingErrors(vec![msg]))? |
| 710 | { |
| 711 | continue; |
| 712 | } |
| 713 | self.collect_import_closure( |
| 714 | &resolved.key, |
| 715 | &resolved.source, |
| 716 | resolved.source_path, |
| 717 | order, |
| 718 | visited, |
| 719 | stack, |
| 720 | stack_keys, |
| 721 | stack_sources, |
| 722 | )?; |
| 723 | } |
| 724 | |
| 725 | stack.pop(); |
| 726 | stack_keys.pop(); |
| 727 | stack_sources.pop(); |
| 728 | visited.insert(name.to_owned()); |
| 729 | order.push((name.to_owned(), source.to_owned(), source_path)); |
| 730 | Ok(()) |
| 731 | } |
| 732 | |
| 733 | /// Compile the stdlib for `mode` as independent per-module objects (no source |
| 734 | /// concatenation), to link alongside the user program. Kernel gets its prefix. |
| 735 | pub fn compile_stdlib_objects( |
| 736 | mode: TargetMode, |
| 737 | ) -> Result<Vec<(String, AssembledOutput)>, CompilationError> { |
| 738 | let mut pipeline = CompilationPipeline::new(); |
| 739 | pipeline.set_target_mode(mode); |
| 740 | pipeline.set_write_artifacts(false); |
| 741 | pipeline.set_string_prefix(Some( |
| 742 | if mode == TargetMode::Kernel { |
| 743 | "__kern_" |
| 744 | } else { |
| 745 | "__stdlib_" |
| 746 | } |
| 747 | .to_owned(), |
| 748 | )); |
| 749 | let modules = hll_to_ir::stdlib::get_stdlib_modules_for_mode(mode); |
| 750 | let mut objects = Vec::with_capacity(modules.len()); |
| 751 | for (module_name, source) in &modules { |
| 752 | // Attribute each module to its real source file so stdlib code the |
| 753 | // debugger steps through maps back to workspace lines. |
| 754 | let path = hll_to_ir::stdlib::stdlib_module_source_path(mode, module_name); |