rustpython_compiler/
lib.rs1use rustpython_codegen::{compile, symboltable};
2use rustpython_parser::ast::{self as ast, fold::Fold, ConstantOptimizer};
3
4pub use rustpython_codegen::compile::CompileOpts;
5pub use rustpython_compiler_core::{bytecode::CodeObject, Mode};
6pub use rustpython_parser::{source_code::LinearLocator, Parse};
7
8pub use rustpython_codegen as codegen;
10pub use rustpython_compiler_core as core;
11pub use rustpython_parser as parser;
12
13#[derive(Debug)]
14pub enum CompileErrorType {
15 Codegen(rustpython_codegen::error::CodegenErrorType),
16 Parse(parser::ParseErrorType),
17}
18
19impl std::error::Error for CompileErrorType {
20 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
21 match self {
22 CompileErrorType::Codegen(e) => e.source(),
23 CompileErrorType::Parse(e) => e.source(),
24 }
25 }
26}
27impl std::fmt::Display for CompileErrorType {
28 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
29 match self {
30 CompileErrorType::Codegen(e) => e.fmt(f),
31 CompileErrorType::Parse(e) => e.fmt(f),
32 }
33 }
34}
35impl From<rustpython_codegen::error::CodegenErrorType> for CompileErrorType {
36 fn from(source: rustpython_codegen::error::CodegenErrorType) -> Self {
37 CompileErrorType::Codegen(source)
38 }
39}
40impl From<parser::ParseErrorType> for CompileErrorType {
41 fn from(source: parser::ParseErrorType) -> Self {
42 CompileErrorType::Parse(source)
43 }
44}
45
46pub type CompileError = rustpython_parser::source_code::LocatedError<CompileErrorType>;
47
48pub fn compile(
50 source: &str,
51 mode: Mode,
52 source_path: String,
53 opts: CompileOpts,
54) -> Result<CodeObject, CompileError> {
55 let mut locator = LinearLocator::new(source);
56 let mut ast = match parser::parse(source, mode.into(), &source_path) {
57 Ok(x) => x,
58 Err(e) => return Err(locator.locate_error(e)),
59 };
60 if opts.optimize > 0 {
61 ast = ConstantOptimizer::new()
62 .fold_mod(ast)
63 .unwrap_or_else(|e| match e {});
64 }
65 let ast = locator.fold_mod(ast).unwrap_or_else(|e| match e {});
66 compile::compile_top(&ast, source_path, mode, opts).map_err(|e| e.into())
67}
68
69pub fn compile_symtable(
70 source: &str,
71 mode: Mode,
72 source_path: &str,
73) -> Result<symboltable::SymbolTable, CompileError> {
74 let mut locator = LinearLocator::new(source);
75 let res = match mode {
76 Mode::Exec | Mode::Single | Mode::BlockExpr => {
77 let ast =
78 ast::Suite::parse(source, source_path).map_err(|e| locator.locate_error(e))?;
79 let ast = locator.fold(ast).unwrap();
80 symboltable::SymbolTable::scan_program(&ast)
81 }
82 Mode::Eval => {
83 let expr =
84 ast::Expr::parse(source, source_path).map_err(|e| locator.locate_error(e))?;
85 let expr = locator.fold(expr).unwrap();
86 symboltable::SymbolTable::scan_expr(&expr)
87 }
88 };
89 res.map_err(|e| e.into_codegen_error(source_path.to_owned()).into())
90}