use crate::ast::{Expr, Program, Stmt, Type};
use anyhow::Result;
pub trait CodeGeneratorCapability {
fn generate(&mut self, program: &Program) -> Result<String>;
fn generate_statement(&mut self, stmt: &Stmt) -> Result<String>;
fn generate_expression(&mut self, expr: &Expr) -> Result<String>;
}
pub trait AssemblyOutput {
fn emit(&mut self, code: &str);
fn emit_label(&mut self, label: &str);
fn emit_comment(&mut self, comment: &str);
fn get_output(&self) -> &str;
fn clear(&mut self);
fn emit_line(&mut self, indent: u8, code: &str);
}
pub trait VariableManager {
fn allocate_variable(&mut self, name: &str, typ: &Type) -> Result<i32>;
fn get_variable_offset(&self, name: &str) -> Option<i32>;
fn enter_scope(&mut self, name: &str);
fn exit_scope(&mut self);
fn scope_depth(&self) -> usize;
}
pub trait RegisterAllocator {
fn allocate_register(&mut self, var_name: &str) -> Result<String>;
fn free_register(&mut self, register: &str);
fn get_available_registers(&self) -> Vec<String>;
fn spill_register(&mut self, register: &str) -> Result<String>;
fn save_register_state(&mut self);
fn restore_register_state(&mut self);
}
pub trait TargetArchitecture {
fn architecture_name(&self) -> &str;
fn register_size(&self) -> usize;
fn stack_alignment(&self) -> usize;
fn calling_convention(&self) -> &str;
fn caller_saved_registers(&self) -> Vec<String>;
fn callee_saved_registers(&self) -> Vec<String>;
fn parameter_registers(&self) -> Vec<String>;
fn return_register(&self) -> &str;
}
pub trait FunctionCalling {
fn generate_prologue(&mut self, name: &str, stack_size: i32) -> Result<()>;
fn generate_epilogue(&mut self) -> Result<()>;
fn generate_call(&mut self, name: &str, args: &[Expr]) -> Result<()>;
fn generate_return(&mut self, value: Option<&Expr>) -> Result<()>;
}
pub trait ControlFlowGenerator {
fn generate_if_then_else(
&mut self,
condition: &Expr,
then_block: &[Stmt],
else_block: Option<&[Stmt]>,
) -> Result<()>;
fn generate_while_loop(&mut self, condition: &Expr, body: &[Stmt]) -> Result<()>;
fn generate_for_loop(
&mut self,
variable: &str,
start: &Expr,
end: &Expr,
step: Option<&Expr>,
body: &[Stmt],
direction: crate::ast::ForDirection,
) -> Result<()>;
fn generate_repeat_loop(&mut self, body: &[Stmt], condition: &Expr) -> Result<()>;
}
pub trait DebugInfo {
fn generate_debug_info(&mut self, program: &Program) -> Result<String>;
fn add_debug_symbol(&mut self, name: &str, address: usize);
fn generate_line_mapping(&mut self, source: &str) -> Result<String>;
fn emit_debug_location(&mut self, line: usize, column: usize);
}