Files
DSA/tooling/dscs_compiler/src/backend/intermediate_rep.rs
T
2026-08-20 18:17:06 +01:00

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
}