forked from RustPython/RustPython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlib.rs
More file actions
89 lines (81 loc) · 2.89 KB
/
lib.rs
File metadata and controls
89 lines (81 loc) · 2.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use rustpython_codegen::{compile, symboltable};
use rustpython_parser::{
self as parser,
ast::{fold::Fold, ConstantOptimizer},
};
pub use rustpython_codegen::compile::CompileOpts;
pub use rustpython_compiler_core::{BaseError as CompileErrorBody, CodeObject, Mode};
use std::error::Error as StdError;
use std::fmt;
#[derive(Debug)]
pub enum CompileErrorType {
Codegen(rustpython_codegen::error::CodegenErrorType),
Parse(parser::ParseErrorType),
}
impl StdError for CompileErrorType {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
match self {
CompileErrorType::Codegen(e) => e.source(),
CompileErrorType::Parse(e) => e.source(),
}
}
}
impl fmt::Display for CompileErrorType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CompileErrorType::Codegen(e) => e.fmt(f),
CompileErrorType::Parse(e) => e.fmt(f),
}
}
}
impl From<rustpython_codegen::error::CodegenErrorType> for CompileErrorType {
fn from(source: rustpython_codegen::error::CodegenErrorType) -> Self {
CompileErrorType::Codegen(source)
}
}
impl From<parser::ParseErrorType> for CompileErrorType {
fn from(source: parser::ParseErrorType) -> Self {
CompileErrorType::Parse(source)
}
}
pub type CompileError = rustpython_compiler_core::CompileError<CompileErrorType>;
fn error_from_parse(error: parser::ParseError, source: &str) -> CompileError {
let error: CompileErrorBody<parser::ParseErrorType> = error.into();
CompileError::from(error, source)
}
/// Compile a given source code into a bytecode object.
pub fn compile(
source: &str,
mode: compile::Mode,
source_path: String,
opts: CompileOpts,
) -> Result<CodeObject, CompileError> {
let mut ast = match parser::parse(source, mode.into(), &source_path) {
Ok(x) => x,
Err(e) => return Err(error_from_parse(e, source)),
};
if opts.optimize > 0 {
ast = ConstantOptimizer::new()
.fold_mod(ast)
.unwrap_or_else(|e| match e {});
}
compile::compile_top(&ast, source_path, mode, opts).map_err(|e| CompileError::from(e, source))
}
pub fn compile_symtable(
source: &str,
mode: compile::Mode,
source_path: &str,
) -> Result<symboltable::SymbolTable, CompileError> {
let parse_err = |e| error_from_parse(e, source);
let res = match mode {
compile::Mode::Exec | compile::Mode::Single | compile::Mode::BlockExpr => {
let ast = parser::parse_program(source, source_path).map_err(parse_err)?;
symboltable::SymbolTable::scan_program(&ast)
}
compile::Mode::Eval => {
let expr = parser::parse_expression(source, source_path).map_err(parse_err)?;
symboltable::SymbolTable::scan_expr(&expr)
}
};
res.map_err(|e| CompileError::from(e.into_codegen_error(source_path.to_owned()), source))
}