pub mod token; pub mod lexer; pub mod ast; pub mod parser; pub mod types; pub mod symbols; pub mod collector; pub mod resolver; pub mod typecheck; pub mod lowering; pub mod contracts; pub use lexer::Lexer; pub use token::{Token, TokenKind}; pub use symbols::{Symbol, SymbolTable, ModuleSymbols, Visibility, SymbolKind, Namespace}; pub use collector::SymbolCollector; pub use resolver::{Resolver, ModuleProvider}; pub use typecheck::TypeChecker; pub use lowering::Lowerer; use crate::common::diagnostics::DiagnosticBundle; use crate::common::files::FileManager; use crate::frontends::Frontend; use crate::ir_vm; use crate::lowering::core_to_vm; use std::path::Path; pub struct PbsFrontend; impl Frontend for PbsFrontend { fn language(&self) -> &'static str { "pbs" } fn compile_to_ir( &self, entry: &Path, file_manager: &mut FileManager, ) -> Result { let source = std::fs::read_to_string(entry).map_err(|e| { DiagnosticBundle::error(format!("Failed to read file: {}", e), None) })?; let file_id = file_manager.add(entry.to_path_buf(), source.clone()); let mut parser = parser::Parser::new(&source, file_id); let ast = parser.parse_file()?; let mut collector = SymbolCollector::new(); let (type_symbols, value_symbols) = collector.collect(&ast)?; let mut module_symbols = ModuleSymbols { type_symbols, value_symbols }; struct EmptyProvider; impl ModuleProvider for EmptyProvider { fn get_module_symbols(&self, _path: &str) -> Option<&ModuleSymbols> { None } } let mut resolver = Resolver::new(&module_symbols, &EmptyProvider); resolver.resolve(&ast)?; let mut typechecker = TypeChecker::new(&mut module_symbols, &EmptyProvider); typechecker.check(&ast)?; // Lower to Core IR let lowerer = Lowerer::new(&module_symbols); let module_name = entry.file_stem().unwrap().to_string_lossy(); let core_program = lowerer.lower_file(&ast, &module_name)?; // Validate Core IR Invariants crate::ir_core::validate_program(&core_program).map_err(|e| { DiagnosticBundle::error(format!("Core IR Invariant Violation: {}", e), None) })?; // Lower Core IR to VM IR core_to_vm::lower_program(&core_program).map_err(|e| { DiagnosticBundle::error(format!("Lowering error: {}", e), None) }) } }