use rustpython_codegen::{compile, symboltable}; use rustpython_parser::ast::{self as ast, fold::Fold, ConstantOptimizer}; pub use rustpython_codegen::compile::CompileOpts; pub use rustpython_compiler_core::{bytecode::CodeObject, Mode}; pub use rustpython_parser::{source_code::LinearLocator, Parse}; // these modules are out of repository. re-exporting them here for convenience. pub use rustpython_codegen as codegen; pub use rustpython_compiler_core as core; pub use rustpython_parser as parser; #[derive(Debug)] pub enum CompileErrorType { Codegen(rustpython_codegen::error::CodegenErrorType), Parse(parser::ParseErrorType), } impl std::error::Error for CompileErrorType { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { CompileErrorType::Codegen(e) => e.source(), CompileErrorType::Parse(e) => e.source(), } } } impl std::fmt::Display for CompileErrorType { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { CompileErrorType::Codegen(e) => e.fmt(f), CompileErrorType::Parse(e) => e.fmt(f), } } } impl From for CompileErrorType { fn from(source: rustpython_codegen::error::CodegenErrorType) -> Self { CompileErrorType::Codegen(source) } } impl From for CompileErrorType { fn from(source: parser::ParseErrorType) -> Self { CompileErrorType::Parse(source) } } pub type CompileError = rustpython_parser::source_code::LocatedError; /// Compile a given source code into a bytecode object. pub fn compile( source: &str, mode: Mode, source_path: String, opts: CompileOpts, ) -> Result { let mut locator = LinearLocator::new(source); let mut ast = match parser::parse(source, mode.into(), &source_path) { Ok(x) => x, Err(e) => return Err(locator.locate_error(e)), }; if opts.optimize > 0 { ast = ConstantOptimizer::new() .fold_mod(ast) .unwrap_or_else(|e| match e {}); } let ast = locator.fold_mod(ast).unwrap_or_else(|e| match e {}); compile::compile_top(&ast, source_path, mode, opts).map_err(|e| e.into()) } pub fn compile_symtable( source: &str, mode: Mode, source_path: &str, ) -> Result { let mut locator = LinearLocator::new(source); let res = match mode { Mode::Exec | Mode::Single | Mode::BlockExpr => { let ast = ast::Suite::parse(source, source_path).map_err(|e| locator.locate_error(e))?; let ast = locator.fold(ast).unwrap(); symboltable::SymbolTable::scan_program(&ast) } Mode::Eval => { let expr = ast::Expr::parse(source, source_path).map_err(|e| locator.locate_error(e))?; let expr = locator.fold(expr).unwrap(); symboltable::SymbolTable::scan_expr(&expr) } }; res.map_err(|e| e.into_codegen_error(source_path.to_owned()).into()) }