citadel_backend/asm/utils/
mod.rs1pub mod codegen;
2
3use std::{fs::File, io::Write, path::PathBuf};
4
5use citadel_frontend::ir::{irgen::HIRStream, IRStmt};
6
7use crate::{
8 api::Target,
9 asm::{
10 codegen::CodeGenerator,
11 elements::{AsmElement, BuiltinFunction},
12 },
13};
14
15use super::elements::{Declaration, Directive, DirectiveType, Operand};
16
17pub fn compile_program(input: HIRStream, _target: impl Target) -> Vec<AsmElement> {
18 let mut codegen = CodeGenerator::new(input.types);
19
20 gen_code(&input.stream, &mut codegen);
21
22 gen_defined_functions(&mut codegen);
23
24 let rodata = codegen.rodata;
25 let data = codegen.data;
26 let mut out = codegen.out;
27
28 add_data_section(rodata, DirectiveType::Rodata, &mut out);
30 add_data_section(data, DirectiveType::Data, &mut out);
31
32 out
33}
34
35fn gen_code<'c>(input: &'c [IRStmt<'c>], codegen: &mut CodeGenerator<'c>) {
36 for stmt in input.iter() {
37 codegen.gen_stmt(stmt);
38 }
39}
40
41fn add_data_section(data: Vec<Declaration>, _type: DirectiveType, out: &mut Vec<AsmElement>) {
43 if !data.is_empty() {
44 out.insert(0, AsmElement::Directive(Directive { _type }));
45 for (i, decl) in data.into_iter().enumerate() {
46 out.insert(i + 1, AsmElement::Declaration(decl));
47 }
48 }
49}
50
51fn gen_defined_functions(codegen: &mut CodeGenerator) {
52 for func in codegen.defined_functions.clone() {
53 func.generate(codegen);
54 }
55}
56
57pub fn compiler_output(asm: String, location: PathBuf) {
58 let mut file = File::create(&location).unwrap_or_else(|err| {
59 panic!(
60 "Failed to create a new file at {}, error: {}",
61 location.display(),
62 err
63 )
64 });
65 file.write_all(asm.as_bytes())
66 .expect("Failed to write to file");
67}
68
69pub fn format(asm: &[AsmElement]) -> String{
70 let mut out = String::new();
71 for elem in asm{
72 match elem {
73 AsmElement::Directive(_) | AsmElement::Label(_) => (),
74 _ => out.push_str(" "),
75 }
76 out.push_str(&elem.to_string());
77 out.push('\n');
78 }
79 out
80}
81
82pub fn op_vec_to_string(vec: &[Operand]) -> String {
83 let str: String = vec
84 .iter()
85 .map(|op| {
86 let mut str = op.to_string();
87 str.push(',');
88 str
89 })
90 .collect();
91 if !vec.is_empty() {
92 (&str[..str.len() - 1]).into()
93 } else {
94 String::new()
95 }
96}
97
98