103 lines
1.9 KiB
Rust
103 lines
1.9 KiB
Rust
use std::fmt;
|
|
use std::fmt::Formatter;
|
|
use std::rc::Rc;
|
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
|
|
|
pub enum Statement {
|
|
Const(VirtualReg, Literal),
|
|
BinaryOp { left: VirtualReg, op: PrimitiveOperation,
|
|
right: VirtualReg, result: VirtualReg },
|
|
AddressOf {
|
|
value: VirtualReg, result: VirtualReg },
|
|
Dereference {
|
|
address: VirtualReg, result: VirtualReg },
|
|
GetStructField {
|
|
struct_addr: VirtualReg, result: VirtualReg, offset: usize },
|
|
SetStructField {
|
|
struct_addr: VirtualReg, value: VirtualReg, offset: usize },
|
|
Call {
|
|
return_value: VirtualReg, func: FunctionName, args: Vec<VirtualReg> },
|
|
}
|
|
|
|
pub struct IRProgram {
|
|
pub functions: Vec<Function>,
|
|
}
|
|
|
|
pub struct Function {
|
|
pub name: FunctionName,
|
|
pub params: Vec<VirtualReg>,
|
|
pub blocks: Vec<BasicBlock>,
|
|
}
|
|
|
|
pub struct BasicBlock {
|
|
pub label: Label,
|
|
pub statements: Vec<Statement>,
|
|
pub terminator: Terminator,
|
|
}
|
|
|
|
pub enum Terminator {
|
|
Jump(Label),
|
|
ConditionalJump { if_flag: VirtualReg, then_goto: Label, else_goto: Label },
|
|
Return(VirtualReg),
|
|
ReturnVoid,
|
|
}
|
|
|
|
pub type FunctionName = String;
|
|
|
|
|
|
#[derive(Clone)]
|
|
pub struct Label {
|
|
id: usize,
|
|
name: Rc<String>
|
|
}
|
|
|
|
impl Label {
|
|
pub fn new_with_id(name: impl Into<String>, id: usize) -> Self {
|
|
Self { id, name: Rc::new(name.into()) }
|
|
}
|
|
|
|
pub fn new(name: impl Into<String>) -> Self {
|
|
Self { id: Self::get_new_id(), name: Rc::new(name.into()) }
|
|
}
|
|
|
|
pub fn get_new_id() -> usize {
|
|
LABEL_ID.fetch_add(1, Ordering::Relaxed)
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Label {
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
|
write!(f, "__{}_{}", self.name, self.id)
|
|
}
|
|
}
|
|
|
|
static LABEL_ID: AtomicUsize = AtomicUsize::new(0);
|
|
|
|
|
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
pub struct VirtualReg(pub isize);
|
|
|
|
impl VirtualReg {
|
|
pub fn void() -> Self {
|
|
Self(-1)
|
|
}
|
|
}
|
|
|
|
|
|
pub enum Literal {
|
|
UInt(usize),
|
|
Int(isize),
|
|
Char(char),
|
|
}
|
|
|
|
pub enum PrimitiveOperation {
|
|
Add,
|
|
Sub,
|
|
And,
|
|
Or,
|
|
Xor,
|
|
Nor,
|
|
Nand
|
|
}
|
|
|