use std::rc::Rc;
#[derive(Debug, Clone)]
pub struct Program {
pub items: Vec<TopLevel>,
}
#[derive(Debug, Clone)]
pub enum TopLevel {
Import(ImportDecl),
Func(FuncDecl),
Struct(StructDecl),
Class(ClassDecl),
Const(ConstDecl),
Impl(ImplBlock),
Enum(EnumDecl),
}
#[derive(Debug, Clone)]
pub struct ImplBlock {
pub ty: String, pub methods: Vec<FuncDecl>,
}
#[derive(Debug, Clone)]
pub struct EnumDecl {
pub name: String,
pub variants: Vec<EnumVariant>,
}
#[derive(Debug, Clone)]
pub struct EnumVariant {
pub name: String,
pub fields: Vec<Type>, }
#[derive(Debug, Clone)]
pub struct ImportDecl {
pub module_path: Vec<String>,
pub alias: Option<String>,
}
#[derive(Debug, Clone)]
pub struct FuncDecl {
pub name: String,
pub type_params: Vec<String>,
pub params: Vec<Param>,
pub ret_type: Option<Type>,
pub body: Block,
}
#[derive(Debug, Clone)]
pub struct Param {
pub name: String,
pub ty: Option<Type>,
pub mutable: bool, pub default: Option<Expr>,
}
#[derive(Debug, Clone)]
pub struct StructDecl {
pub name: String,
pub type_params: Vec<String>,
pub fields: Vec<Field>,
}
#[derive(Debug, Clone)]
pub struct ClassDecl {
pub name: String,
pub base: Option<String>,
pub body: Block,
}
#[derive(Debug, Clone)]
pub struct ConstDecl {
pub name: String,
pub ty: Option<Type>,
pub value: Expr,
}
#[derive(Debug, Clone)]
pub struct Field {
pub name: String,
pub ty: Type,
pub default: Option<Expr>,
}
#[derive(Debug, Clone)]
pub struct Block {
pub statements: Vec<Stmt>,
}
#[derive(Debug, Clone)]
pub enum Stmt {
VarDecl(VarDecl),
Expr(Expr),
If(IfStmt),
For(ForStmt),
While(WhileStmt),
Return(Option<Expr>),
Match(MatchStmt),
}
#[derive(Debug, Clone)]
pub struct VarDecl {
pub name: String,
pub ty: Option<Type>,
pub init: Expr,
}
#[derive(Debug, Clone)]
pub struct IfStmt {
pub condition: Expr,
pub then_branch: Block,
pub elif_branches: Vec<(Expr, Block)>,
pub else_branch: Option<Block>,
}
#[derive(Debug, Clone)]
pub struct ForStmt {
pub init: Option<Box<Stmt>>, pub condition: Expr,
pub update: Option<Box<Stmt>>, pub body: Block,
}
#[derive(Debug, Clone)]
pub struct WhileStmt {
pub condition: Expr,
pub body: Block,
}
#[derive(Debug, Clone)]
pub struct MatchStmt {
pub expr: Expr,
pub arms: Vec<(Pattern, Block)>,
}
#[derive(Debug, Clone)]
pub enum Pattern {
Lit(Literal),
Ident(String),
Wildcard,
}
#[derive(Debug, Clone)]
pub enum Expr {
Literal(Literal),
Ident(String),
Binary(Box<Expr>, BinOp, Box<Expr>),
Unary(UnOp, Box<Expr>),
Call(Box<Expr>, Vec<Expr>),
MethodCall(Box<Expr>, String, Vec<Expr>), Lambda(Vec<Param>, Box<Expr>),
List(Vec<Expr>),
Dict(Vec<(Expr, Expr)>),
Index(Box<Expr>, Box<Expr>), FieldAccess(Box<Expr>, String), StructInit(String, Vec<(String, Expr)>), Assign(Box<Expr>, Box<Expr>), CompoundAssign(Box<Expr>, BinOp, Box<Expr>), Block(Block), }
#[derive(Debug, Clone)]
pub enum Literal {
Int(i64),
Float(f64),
Bool(bool),
String(Rc<str>),
Char(char),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BinOp {
Add,
Sub,
Mul,
Div,
Mod,
Eq,
NotEq,
Lt,
Gt,
LtEq,
GtEq,
And,
Or,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UnOp {
Neg,
Not,
}
#[derive(Debug, Clone)]
pub enum Type {
Named(String, Vec<Type>), Int,
Float,
Bool,
String,
Void,
Auto,
Array(Box<Type>, Option<usize>), Function(Vec<Type>, Box<Type>), Tuple(Vec<Type>), }