codegen basics
This commit is contained in:
parent
a62432bfbb
commit
c9a7493006
15 changed files with 1151 additions and 50 deletions
157
src/c_ir.rs
157
src/c_ir.rs
|
|
@ -0,0 +1,157 @@
|
|||
#[derive(Debug, Clone)]
|
||||
pub enum CType {
|
||||
Void,
|
||||
Int,
|
||||
Float,
|
||||
Bool,
|
||||
Char,
|
||||
Ptr(Box<CType>),
|
||||
Struct(String),
|
||||
UnnamedStruct(Vec<CVarDecl>),
|
||||
Array(Box<CType>, usize), // type and size
|
||||
Func(Vec<CType>, Box<CType>), // args and return
|
||||
}
|
||||
|
||||
impl CType {
|
||||
pub fn to_string(&self) -> String {
|
||||
match self {
|
||||
CType::Void => "void".to_string(),
|
||||
CType::Int => "int".to_string(),
|
||||
CType::Float => "float".to_string(),
|
||||
CType::Bool => "bool".to_string(),
|
||||
CType::Char => "char".to_string(),
|
||||
CType::Ptr(inner) => format!("{}*", inner.to_string()),
|
||||
CType::Struct(name) => format!("struct {}", name),
|
||||
CType::UnnamedStruct(fields) => {
|
||||
let field_strs: Vec<String> = fields
|
||||
.iter()
|
||||
.map(|f| format!(" {} {};", f.ty.to_string(), f.name))
|
||||
.collect();
|
||||
format!("struct {{\n{}\n}}", field_strs.join("\n"))
|
||||
}
|
||||
CType::Array(inner, size) => format!("{}[{}]", inner.to_string(), size),
|
||||
CType::Func(args, ret) => {
|
||||
let arg_strs: Vec<String> = args.iter().map(|t| t.to_string()).collect();
|
||||
format!("{} (*)({})", ret.to_string(), arg_strs.join(", "))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CVarDecl {
|
||||
pub name: String,
|
||||
pub ty: CType,
|
||||
pub initializer: Option<CExpr>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CStructDecl {
|
||||
pub name: String,
|
||||
pub fields: Vec<CVarDecl>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CFuncDecl {
|
||||
pub name: String,
|
||||
pub return_type: CType,
|
||||
pub params: Vec<CVarDecl>,
|
||||
pub body: Option<Vec<CStmt>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CExpr {
|
||||
IntLit(i64),
|
||||
FloatLit(f64),
|
||||
BoolLit(bool),
|
||||
StringLit(String),
|
||||
Var(String),
|
||||
Call(String, Vec<CExpr>),
|
||||
BinOp(Box<CExpr>, CBinaryOp, Box<CExpr>),
|
||||
UnOp(CUnaryOp, Box<CExpr>),
|
||||
Cast(Box<CExpr>, CType),
|
||||
StructLit(String, Vec<(String, CExpr)>),
|
||||
EnumLit(String, String, Vec<CExpr>), // enum_name, variant_name, args
|
||||
ArrayLit(Vec<CExpr>),
|
||||
Index(Box<CExpr>, Box<CExpr>),
|
||||
Dot(Box<CExpr>, String),
|
||||
AddrOf(Box<CExpr>),
|
||||
Deref(Box<CExpr>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CBinaryOp {
|
||||
Add,
|
||||
Sub,
|
||||
Mul,
|
||||
Div,
|
||||
Mod,
|
||||
Eq,
|
||||
Neq,
|
||||
Lt,
|
||||
Gt,
|
||||
Leq,
|
||||
Geq,
|
||||
And,
|
||||
Or,
|
||||
}
|
||||
|
||||
impl CBinaryOp {
|
||||
pub fn to_string(&self) -> &'static str {
|
||||
match self {
|
||||
CBinaryOp::Add => "+",
|
||||
CBinaryOp::Sub => "-",
|
||||
CBinaryOp::Mul => "*",
|
||||
CBinaryOp::Div => "/",
|
||||
CBinaryOp::Mod => "%",
|
||||
CBinaryOp::Eq => "==",
|
||||
CBinaryOp::Neq => "!=",
|
||||
CBinaryOp::Lt => "<",
|
||||
CBinaryOp::Gt => ">",
|
||||
CBinaryOp::Leq => "<=",
|
||||
CBinaryOp::Geq => ">=",
|
||||
CBinaryOp::And => "&&",
|
||||
CBinaryOp::Or => "||",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CUnaryOp {
|
||||
Neg,
|
||||
Not,
|
||||
Ref,
|
||||
Deref,
|
||||
}
|
||||
|
||||
impl CUnaryOp {
|
||||
pub fn to_string(&self) -> &'static str {
|
||||
match self {
|
||||
CUnaryOp::Neg => "-",
|
||||
CUnaryOp::Not => "!",
|
||||
CUnaryOp::Ref => "&",
|
||||
CUnaryOp::Deref => "*",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CStmt {
|
||||
VarDecl(CVarDecl),
|
||||
Expr(CExpr),
|
||||
Assign(CExpr, CExpr),
|
||||
If(CExpr, Vec<CStmt>, Option<Vec<CStmt>>),
|
||||
While(CExpr, Vec<CStmt>),
|
||||
For(CVarDecl, CExpr, CExpr, Vec<CStmt>), // init, cond, incr, body
|
||||
Return(Option<CExpr>),
|
||||
Break,
|
||||
Continue,
|
||||
Block(Vec<CStmt>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CToplevel {
|
||||
StructDecl(CStructDecl),
|
||||
FuncDecl(CFuncDecl),
|
||||
VarDecl(CVarDecl),
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue