use crate::lexer::Span; #[derive(Debug, Clone)] pub struct Program { pub game: GameDecl, pub globals: Vec, pub constants: Vec, pub functions: Vec, pub states: Vec, pub sprites: Vec, pub palettes: Vec, pub backgrounds: Vec, pub banks: Vec, pub start_state: String, pub span: Span, } #[derive(Debug, Clone)] pub struct SpriteDecl { pub name: String, pub chr_source: AssetSource, pub span: Span, } #[derive(Debug, Clone)] pub struct PaletteDecl { pub name: String, pub colors: Vec, pub span: Span, } #[derive(Debug, Clone)] pub struct BackgroundDecl { pub name: String, pub chr_source: AssetSource, pub span: Span, } #[derive(Debug, Clone)] pub enum AssetSource { Chr(String), Binary(String), Inline(Vec), } #[derive(Debug, Clone)] pub struct GameDecl { pub name: String, pub mapper: Mapper, pub mirroring: Mirroring, pub span: Span, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Mapper { NROM, MMC1, UxROM, MMC3, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Mirroring { Horizontal, Vertical, } #[derive(Debug, Clone)] pub struct BankDecl { pub name: String, pub bank_type: BankType, pub span: Span, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum BankType { Prg, Chr, } #[derive(Debug, Clone)] pub struct StateDecl { pub name: String, pub locals: Vec, pub on_enter: Option, pub on_exit: Option, pub on_frame: Option, pub on_scanline: Vec<(u8, Block)>, pub span: Span, } #[derive(Debug, Clone)] pub struct FunDecl { pub name: String, pub params: Vec, pub return_type: Option, pub body: Block, pub is_inline: bool, pub span: Span, } #[derive(Debug, Clone)] pub struct Param { pub name: String, pub param_type: NesType, } #[derive(Debug, Clone)] pub struct VarDecl { pub name: String, pub var_type: NesType, pub init: Option, pub placement: Placement, pub span: Span, } #[derive(Debug, Clone)] pub struct ConstDecl { pub name: String, pub const_type: NesType, pub value: Expr, pub span: Span, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Placement { Fast, Slow, Auto, } #[derive(Debug, Clone, PartialEq, Eq)] pub enum NesType { U8, I8, U16, Bool, Array(Box, u16), } impl std::fmt::Display for NesType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::U8 => write!(f, "u8"), Self::I8 => write!(f, "i8"), Self::U16 => write!(f, "u16"), Self::Bool => write!(f, "bool"), Self::Array(t, n) => write!(f, "{t}[{n}]"), } } } #[derive(Debug, Clone)] pub struct Block { pub statements: Vec, pub span: Span, } #[derive(Debug, Clone)] pub enum Expr { IntLiteral(u16, Span), BoolLiteral(bool, Span), Ident(String, Span), ArrayIndex(String, Box, Span), BinaryOp(Box, BinOp, Box, Span), UnaryOp(UnaryOp, Box, Span), Call(String, Vec, Span), ButtonRead(Option, String, Span), ArrayLiteral(Vec, Span), Cast(Box, NesType, Span), } impl Expr { pub fn span(&self) -> Span { match self { Self::IntLiteral(_, s) | Self::BoolLiteral(_, s) | Self::Ident(_, s) | Self::ArrayIndex(_, _, s) | Self::BinaryOp(_, _, _, s) | Self::UnaryOp(_, _, s) | Self::Call(_, _, s) | Self::ButtonRead(_, _, s) | Self::ArrayLiteral(_, s) | Self::Cast(_, _, s) => *s, } } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum BinOp { Add, Sub, Mul, Div, Mod, BitwiseAnd, BitwiseOr, BitwiseXor, ShiftLeft, ShiftRight, Eq, NotEq, Lt, Gt, LtEq, GtEq, And, Or, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum UnaryOp { Negate, Not, BitNot, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Player { P1, P2, } #[derive(Debug, Clone)] pub enum Statement { VarDecl(VarDecl), Assign(LValue, AssignOp, Expr, Span), If(Expr, Block, Vec<(Expr, Block)>, Option, Span), While(Expr, Block, Span), Loop(Block, Span), Break(Span), Continue(Span), Return(Option, Span), Draw(DrawStmt), Transition(String, Span), WaitFrame(Span), Call(String, Vec, Span), LoadBackground(String, Span), SetPalette(String, Span), Scroll(Expr, Expr, Span), /// debug.log(expr, ...) — writes values to the emulator debug port. /// Stripped in release mode. DebugLog(Vec, Span), /// debug.assert(cond) — runtime check, halts on failure. /// Stripped in release mode. DebugAssert(Expr, Span), } #[derive(Debug, Clone)] pub struct DrawStmt { pub sprite_name: String, pub x: Expr, pub y: Expr, pub frame: Option, pub span: Span, } #[derive(Debug, Clone)] pub enum LValue { Var(String), ArrayIndex(String, Box), } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum AssignOp { Assign, PlusAssign, MinusAssign, AmpAssign, PipeAssign, CaretAssign, ShiftLeftAssign, ShiftRightAssign, }