reid-llvm/reid-llvm-lib/src/lib.rs

200 lines
4.0 KiB
Rust

use std::marker::PhantomData;
use builder::{BlockValue, Builder, FunctionValue, InstructionValue, ModuleValue};
pub mod builder;
pub mod compile;
mod debug;
mod util;
// pub struct InstructionValue(BlockValue, usize);
#[derive(Debug)]
pub struct Context {
builder: Builder,
}
impl Context {
pub fn new() -> Context {
Context {
builder: Builder::new(),
}
}
pub fn module<'ctx>(&'ctx self, name: &str) -> Module<'ctx> {
let value = self.builder.add_module(ModuleData {
name: name.to_owned(),
});
Module {
phantom: PhantomData,
builder: self.builder.clone(),
value,
}
}
}
#[derive(Debug, Clone, Hash)]
pub struct ModuleData {
name: String,
}
pub struct Module<'ctx> {
phantom: PhantomData<&'ctx ()>,
builder: Builder,
value: ModuleValue,
}
impl<'ctx> Module<'ctx> {
pub fn function(&mut self, name: &str, ret: Type, params: Vec<Type>) -> Function<'ctx> {
unsafe {
Function {
phantom: PhantomData,
builder: self.builder.clone(),
value: self.builder.add_function(
&self.value,
FunctionData {
name: name.to_owned(),
ret,
params,
},
),
}
}
}
pub fn value(&self) -> ModuleValue {
self.value
}
}
#[derive(Debug, Clone, Hash)]
pub struct FunctionData {
name: String,
ret: Type,
params: Vec<Type>,
}
pub struct Function<'ctx> {
phantom: PhantomData<&'ctx ()>,
builder: Builder,
value: FunctionValue,
}
impl<'ctx> Function<'ctx> {
pub fn block(&self, name: &str) -> Block<'ctx> {
unsafe {
Block {
phantom: PhantomData,
builder: self.builder.clone(),
value: self.builder.add_block(
&self.value,
BlockData {
name: name.to_owned(),
terminator: None,
},
),
}
}
}
pub fn value(&self) -> FunctionValue {
self.value
}
}
#[derive(Debug, Clone, Hash)]
pub struct BlockData {
name: String,
terminator: Option<TerminatorKind>,
}
pub struct Block<'builder> {
phantom: PhantomData<&'builder ()>,
builder: Builder,
value: BlockValue,
}
impl<'builder> Block<'builder> {
pub fn build(&mut self, instruction: InstructionKind) -> Result<InstructionValue, ()> {
unsafe {
self.builder
.add_instruction(&self.value, InstructionData { kind: instruction })
}
}
pub fn terminate(&mut self, instruction: TerminatorKind) -> Result<(), ()> {
unsafe { self.builder.terminate(&self.value, instruction) }
}
pub fn value(&self) -> BlockValue {
self.value
}
}
#[derive(Clone, Hash)]
pub struct InstructionData {
kind: InstructionKind,
}
#[derive(Clone, Copy, Hash)]
pub enum CmpPredicate {
LT,
LE,
GT,
GE,
EQ,
NE,
}
#[derive(Clone, Hash)]
pub enum InstructionKind {
Param(usize),
Constant(ConstValue),
Add(InstructionValue, InstructionValue),
Sub(InstructionValue, InstructionValue),
Phi(Vec<InstructionValue>),
/// Integer Comparison
ICmp(CmpPredicate, InstructionValue, InstructionValue),
FunctionCall(FunctionValue, Vec<InstructionValue>),
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
pub enum Type {
I8,
I16,
I32,
I64,
I128,
U8,
U16,
U32,
U64,
U128,
Bool,
Void,
}
#[derive(Debug, Clone, Hash)]
pub enum ConstValue {
I8(i8),
I16(i16),
I32(i32),
I64(i64),
I128(i128),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
U128(u128),
Bool(bool),
}
#[derive(Clone, Hash)]
pub enum TerminatorKind {
Ret(InstructionValue),
Branch(BlockValue),
CondBr(InstructionValue, BlockValue, BlockValue),
}