| 526 | let stdlib_objects = compile_stdlib_objects(mode)?; |
| 527 | let user_tokens = asm_text_to_tokens(&asm_text); |
| 528 | let mut pipeline = make_pipeline(mode, "_u_"); |
| 529 | pipeline.set_artifact_stem(Some(source_stem(path, "module"))); |
| 530 | |
| 531 | let user_obj = pipeline |
| 532 | .assemble_named(&source_stem(path, "module"), &user_tokens) |
| 533 | .map_err(|e| CliError::Assemble(format!("user object assembly failed: {e}")))?; |
| 534 | |
| 535 | let mut modules: Vec<(&str, &AssembledOutput)> = stdlib_objects |
| 536 | .iter() |
| 537 | .map(|(n, o)| (n.as_str(), o)) |
| 538 | .collect(); |
| 539 | modules.push(("user", &user_obj)); |
| 540 | |
| 541 | pipeline |
| 542 | .link_assembled_objects_named(&source_stem(path, "module"), &modules) |
| 543 | .map_err(|e| CliError::Assemble(e.to_string())) |
| 544 | } |
| 545 | |
| 546 | // No source concatenation: each HLL file becomes its own object. |
| 547 | fn compile_stdlib_objects(mode: TargetMode) -> Result<Vec<(String, AssembledOutput)>, CliError> { |
| 548 | let mut pipeline = make_pipeline(mode, "_s_"); |
| 549 | pipeline.set_run_semantic_analysis(false); |
| 550 | pipeline.set_type_prelude(get_stdlib_type_prelude()); |
| 551 | if mode == TargetMode::Kernel { |
| 552 | pipeline.set_string_prefix(Some("__kern_str_".to_owned())); |
| 553 | } |
| 554 | |
| 555 | let modules: Vec<(&str, &str)> = get_stdlib_modules_for_mode(mode); |
| 556 | let objs = pipeline |
| 557 | .compile_modules(&modules) |
| 558 | .map_err(|e| CliError::Compile(format!("stdlib: {e}")))?; |
| 559 | |
| 560 | let named: Vec<(String, AssembledOutput)> = modules |
| 561 | .into_iter() |
| 562 | .map(|(n, _)| n.to_owned()) |
| 563 | .zip(objs) |
| 564 | .collect(); |
| 565 | |
| 566 | Ok(named) |
| 567 | } |
| 568 | |
| 569 | // Pass-0 recognises labels, section directives, and known mnemonics on indented |
| 570 | // lines; unrecognised mnemonics become no-op comments. |
| 571 | fn asm_text_to_tokens(text: &str) -> Vec<RvInstruction> { |
| 572 | text.lines() |
| 573 | .map(|line| RvInstruction::Directive(line.to_owned())) |
| 574 | .collect() |
| 575 | } |
| 576 | |
| 577 | // --- Pipeline factory --- |
| 578 | |
| 579 | fn make_pipeline(mode: TargetMode, string_prefix: &str) -> CompilationPipeline { |
| 580 | let mut p = CompilationPipeline::new(); |
| 581 | p.set_target_mode(mode); |
| 582 | p.set_string_prefix(Some(string_prefix.to_owned())); |
| 583 | p |
| 584 | } |
| 585 | |