157 lines
3.7 KiB
Rust
157 lines
3.7 KiB
Rust
#[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),
|
|
}
|