mirror of
https://github.com/RustPython/Parser.git
synced 2025-07-16 01:25:25 +00:00
Add compile::Mode::BlockExpr
This commit is contained in:
parent
2262971b12
commit
cb5324d023
3 changed files with 58 additions and 6 deletions
|
@ -76,12 +76,12 @@ pub fn compile(
|
||||||
source_path: String,
|
source_path: String,
|
||||||
opts: CompileOpts,
|
opts: CompileOpts,
|
||||||
) -> Result<CodeObject, CompileError> {
|
) -> Result<CodeObject, CompileError> {
|
||||||
let mode = match mode {
|
let parser_mode = match mode {
|
||||||
compile::Mode::Exec => parser::Mode::Module,
|
compile::Mode::Exec => parser::Mode::Module,
|
||||||
compile::Mode::Eval => parser::Mode::Expression,
|
compile::Mode::Eval => parser::Mode::Expression,
|
||||||
compile::Mode::Single => parser::Mode::Interactive,
|
compile::Mode::Single | compile::Mode::BlockExpr => parser::Mode::Interactive,
|
||||||
};
|
};
|
||||||
let mut ast = match parser::parse(source, mode) {
|
let mut ast = match parser::parse(source, parser_mode) {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(e) => return Err(CompileError::from_parse(e, source, source_path)),
|
Err(e) => return Err(CompileError::from_parse(e, source, source_path)),
|
||||||
};
|
};
|
||||||
|
@ -90,7 +90,8 @@ pub fn compile(
|
||||||
.fold_mod(ast)
|
.fold_mod(ast)
|
||||||
.unwrap_or_else(|e| match e {});
|
.unwrap_or_else(|e| match e {});
|
||||||
}
|
}
|
||||||
compile::compile_top(&ast, source_path, opts).map_err(|e| CompileError::from_compile(e, source))
|
compile::compile_top(&ast, source_path, mode, opts)
|
||||||
|
.map_err(|e| CompileError::from_compile(e, source))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_symtable(
|
pub fn compile_symtable(
|
||||||
|
@ -107,7 +108,7 @@ pub fn compile_symtable(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let res = match mode {
|
let res = match mode {
|
||||||
compile::Mode::Exec | compile::Mode::Single => {
|
compile::Mode::Exec | compile::Mode::Single | compile::Mode::BlockExpr => {
|
||||||
let ast = try_parse!(parser::parse_program(source));
|
let ast = try_parse!(parser::parse_program(source));
|
||||||
symboltable::make_symbol_table(&ast)
|
symboltable::make_symbol_table(&ast)
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,11 +104,16 @@ impl CompileContext {
|
||||||
pub fn compile_top(
|
pub fn compile_top(
|
||||||
ast: &ast::Mod,
|
ast: &ast::Mod,
|
||||||
source_path: String,
|
source_path: String,
|
||||||
|
mode: Mode,
|
||||||
opts: CompileOpts,
|
opts: CompileOpts,
|
||||||
) -> CompileResult<CodeObject> {
|
) -> CompileResult<CodeObject> {
|
||||||
match ast {
|
match ast {
|
||||||
ast::Mod::Module { body, .. } => compile_program(body, source_path, opts),
|
ast::Mod::Module { body, .. } => compile_program(body, source_path, opts),
|
||||||
ast::Mod::Interactive { body } => compile_program_single(body, source_path, opts),
|
ast::Mod::Interactive { body } => match mode {
|
||||||
|
Mode::Single => compile_program_single(body, source_path, opts),
|
||||||
|
Mode::BlockExpr => compile_block_expression(body, source_path, opts),
|
||||||
|
_ => unreachable!("only Single and BlockExpr parsed to Interactive"),
|
||||||
|
},
|
||||||
ast::Mod::Expression { body } => compile_expression(body, source_path, opts),
|
ast::Mod::Expression { body } => compile_expression(body, source_path, opts),
|
||||||
ast::Mod::FunctionType { .. } => panic!("can't compile a FunctionType"),
|
ast::Mod::FunctionType { .. } => panic!("can't compile a FunctionType"),
|
||||||
}
|
}
|
||||||
|
@ -164,6 +169,20 @@ pub fn compile_program_single(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn compile_block_expression(
|
||||||
|
ast: &[ast::Stmt],
|
||||||
|
source_path: String,
|
||||||
|
opts: CompileOpts,
|
||||||
|
) -> CompileResult<CodeObject> {
|
||||||
|
compile_impl(
|
||||||
|
ast,
|
||||||
|
source_path,
|
||||||
|
opts,
|
||||||
|
make_symbol_table,
|
||||||
|
Compiler::compile_block_expr,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn compile_expression(
|
pub fn compile_expression(
|
||||||
ast: &ast::Expr,
|
ast: &ast::Expr,
|
||||||
source_path: String,
|
source_path: String,
|
||||||
|
@ -370,6 +389,35 @@ impl Compiler {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compile_block_expr(
|
||||||
|
&mut self,
|
||||||
|
body: &[ast::Stmt],
|
||||||
|
symbol_table: SymbolTable,
|
||||||
|
) -> CompileResult<()> {
|
||||||
|
self.symbol_table_stack.push(symbol_table);
|
||||||
|
|
||||||
|
self.compile_statements(body)?;
|
||||||
|
|
||||||
|
if let Some(last_statement) = body.last() {
|
||||||
|
match last_statement.node {
|
||||||
|
ast::StmtKind::Expr { .. } => {
|
||||||
|
self.current_block().instructions.pop(); // pop Instruction::Pop
|
||||||
|
}
|
||||||
|
ast::StmtKind::FunctionDef { .. }
|
||||||
|
| ast::StmtKind::AsyncFunctionDef { .. }
|
||||||
|
| ast::StmtKind::ClassDef { .. } => {
|
||||||
|
let store_inst = self.current_block().instructions.pop().unwrap(); // pop Instruction::Store
|
||||||
|
self.emit(Instruction::Duplicate);
|
||||||
|
self.current_block().instructions.push(store_inst);
|
||||||
|
}
|
||||||
|
_ => self.emit_constant(ConstantData::None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.emit(Instruction::ReturnValue);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// Compile statement in eval mode:
|
// Compile statement in eval mode:
|
||||||
fn compile_eval(
|
fn compile_eval(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
|
@ -3,10 +3,13 @@ pub enum Mode {
|
||||||
Exec,
|
Exec,
|
||||||
Eval,
|
Eval,
|
||||||
Single,
|
Single,
|
||||||
|
BlockExpr,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::str::FromStr for Mode {
|
impl std::str::FromStr for Mode {
|
||||||
type Err = ModeParseError;
|
type Err = ModeParseError;
|
||||||
|
|
||||||
|
// To support `builtins.compile()` `mode` argument
|
||||||
fn from_str(s: &str) -> Result<Self, ModeParseError> {
|
fn from_str(s: &str) -> Result<Self, ModeParseError> {
|
||||||
match s {
|
match s {
|
||||||
"exec" => Ok(Mode::Exec),
|
"exec" => Ok(Mode::Exec),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue