use codegen_lang::{Program, compile};
use ir_lang::{BinOp, Builder, Type};
use linker_lang::{Linker, Object};
fn main() {
let functions = [double(), square(), main_fn()];
let objects: Vec<Object> = functions.iter().map(object_for).collect();
let image = Linker::new()
.base_address(0x40_0000)
.entry("main")
.link(&objects)
.expect("the three functions have distinct names");
println!("linked {} function(s) into one image:\n", functions.len());
print!("{image}");
println!("\nentry point `main` is at {:#x}", image.entry().unwrap());
}
fn object_for(program: &Program) -> Object {
let code: Vec<u8> = program.ops().iter().map(|_| 0u8).collect();
let mut object = Object::new(program.name());
object.section(".text", code);
object.define(program.name(), ".text", 0);
object
}
fn double() -> Program {
let mut b = Builder::new("double", &[Type::Int], Type::Int);
let x = b.block_params(b.entry())[0];
let sum = b.bin(BinOp::Add, x, x);
b.ret(Some(sum));
compile(&b.finish()).expect("double is well-formed")
}
fn square() -> Program {
let mut b = Builder::new("square", &[Type::Int], Type::Int);
let x = b.block_params(b.entry())[0];
let product = b.bin(BinOp::Mul, x, x);
b.ret(Some(product));
compile(&b.finish()).expect("square is well-formed")
}
fn main_fn() -> Program {
let mut b = Builder::new("main", &[], Type::Unit);
b.ret(None);
compile(&b.finish()).expect("main is well-formed")
}