mirror of
https://github.com/RustPython/Parser.git
synced 2025-07-23 04:55:25 +00:00
Add coroutines, async/await functionality, and gen.close()
This commit is contained in:
parent
47c8f3756b
commit
3638591cde
1 changed files with 31 additions and 9 deletions
|
@ -29,6 +29,7 @@ struct Compiler<O: OutputStream = BasicOutputStream> {
|
||||||
current_qualified_path: Option<String>,
|
current_qualified_path: Option<String>,
|
||||||
in_loop: bool,
|
in_loop: bool,
|
||||||
in_function_def: bool,
|
in_function_def: bool,
|
||||||
|
in_async_func: bool,
|
||||||
optimize: u8,
|
optimize: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +127,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||||
current_qualified_path: None,
|
current_qualified_path: None,
|
||||||
in_loop: false,
|
in_loop: false,
|
||||||
in_function_def: false,
|
in_function_def: false,
|
||||||
|
in_async_func: false,
|
||||||
optimize,
|
optimize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -451,11 +453,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||||
decorator_list,
|
decorator_list,
|
||||||
returns,
|
returns,
|
||||||
} => {
|
} => {
|
||||||
if *is_async {
|
self.compile_function_def(name, args, body, decorator_list, returns, *is_async)?;
|
||||||
unimplemented!("async def");
|
|
||||||
} else {
|
|
||||||
self.compile_function_def(name, args, body, decorator_list, returns)?
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ClassDef {
|
ClassDef {
|
||||||
name,
|
name,
|
||||||
|
@ -797,11 +795,15 @@ impl<O: OutputStream> Compiler<O> {
|
||||||
body: &[ast::Statement],
|
body: &[ast::Statement],
|
||||||
decorator_list: &[ast::Expression],
|
decorator_list: &[ast::Expression],
|
||||||
returns: &Option<ast::Expression>, // TODO: use type hint somehow..
|
returns: &Option<ast::Expression>, // TODO: use type hint somehow..
|
||||||
|
is_async: bool,
|
||||||
) -> Result<(), CompileError> {
|
) -> Result<(), CompileError> {
|
||||||
// Create bytecode for this function:
|
// Create bytecode for this function:
|
||||||
// remember to restore self.in_loop to the original after the function is compiled
|
// remember to restore self.in_loop to the original after the function is compiled
|
||||||
let was_in_loop = self.in_loop;
|
let was_in_loop = self.in_loop;
|
||||||
let was_in_function_def = self.in_function_def;
|
let was_in_function_def = self.in_function_def;
|
||||||
|
|
||||||
|
let was_in_async_func = self.in_async_func;
|
||||||
|
self.in_async_func = is_async;
|
||||||
self.in_loop = false;
|
self.in_loop = false;
|
||||||
self.in_function_def = true;
|
self.in_function_def = true;
|
||||||
|
|
||||||
|
@ -870,6 +872,10 @@ impl<O: OutputStream> Compiler<O> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if is_async {
|
||||||
|
code.flags |= bytecode::CodeFlags::IS_COROUTINE;
|
||||||
|
}
|
||||||
|
|
||||||
self.emit(Instruction::LoadConst {
|
self.emit(Instruction::LoadConst {
|
||||||
value: bytecode::Constant::Code {
|
value: bytecode::Constant::Code {
|
||||||
code: Box::new(code),
|
code: Box::new(code),
|
||||||
|
@ -891,6 +897,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||||
self.current_qualified_path = old_qualified_path;
|
self.current_qualified_path = old_qualified_path;
|
||||||
self.in_loop = was_in_loop;
|
self.in_loop = was_in_loop;
|
||||||
self.in_function_def = was_in_function_def;
|
self.in_function_def = was_in_function_def;
|
||||||
|
self.in_async_func = was_in_async_func;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1551,7 +1558,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||||
self.emit(Instruction::BuildSlice { size });
|
self.emit(Instruction::BuildSlice { size });
|
||||||
}
|
}
|
||||||
Yield { value } => {
|
Yield { value } => {
|
||||||
if !self.in_function_def {
|
if !self.in_function_def || self.in_async_func {
|
||||||
return Err(CompileError {
|
return Err(CompileError {
|
||||||
error: CompileErrorType::InvalidYield,
|
error: CompileErrorType::InvalidYield,
|
||||||
location: self.current_source_location.clone(),
|
location: self.current_source_location.clone(),
|
||||||
|
@ -1566,8 +1573,13 @@ impl<O: OutputStream> Compiler<O> {
|
||||||
};
|
};
|
||||||
self.emit(Instruction::YieldValue);
|
self.emit(Instruction::YieldValue);
|
||||||
}
|
}
|
||||||
Await { .. } => {
|
Await { value } => {
|
||||||
unimplemented!("await");
|
self.compile_expression(value)?;
|
||||||
|
self.emit(Instruction::GetAwaitable);
|
||||||
|
self.emit(Instruction::LoadConst {
|
||||||
|
value: bytecode::Constant::None,
|
||||||
|
});
|
||||||
|
self.emit(Instruction::YieldFrom);
|
||||||
}
|
}
|
||||||
YieldFrom { value } => {
|
YieldFrom { value } => {
|
||||||
self.mark_generator();
|
self.mark_generator();
|
||||||
|
@ -1612,8 +1624,14 @@ impl<O: OutputStream> Compiler<O> {
|
||||||
self.load_name(name);
|
self.load_name(name);
|
||||||
}
|
}
|
||||||
Lambda { args, body } => {
|
Lambda { args, body } => {
|
||||||
|
let was_in_loop = self.in_loop;
|
||||||
|
let was_in_function_def = self.in_function_def;
|
||||||
|
let was_in_async_func = self.in_async_func;
|
||||||
|
self.in_async_func = false;
|
||||||
|
self.in_loop = false;
|
||||||
|
self.in_function_def = true;
|
||||||
|
|
||||||
let name = "<lambda>".to_string();
|
let name = "<lambda>".to_string();
|
||||||
// no need to worry about the self.loop_depth because there are no loops in lambda expressions
|
|
||||||
self.enter_function(&name, args)?;
|
self.enter_function(&name, args)?;
|
||||||
self.compile_expression(body)?;
|
self.compile_expression(body)?;
|
||||||
self.emit(Instruction::ReturnValue);
|
self.emit(Instruction::ReturnValue);
|
||||||
|
@ -1629,6 +1647,10 @@ impl<O: OutputStream> Compiler<O> {
|
||||||
});
|
});
|
||||||
// Turn code object into function object:
|
// Turn code object into function object:
|
||||||
self.emit(Instruction::MakeFunction);
|
self.emit(Instruction::MakeFunction);
|
||||||
|
|
||||||
|
self.in_loop = was_in_loop;
|
||||||
|
self.in_function_def = was_in_function_def;
|
||||||
|
self.in_async_func = was_in_async_func;
|
||||||
}
|
}
|
||||||
Comprehension { kind, generators } => {
|
Comprehension { kind, generators } => {
|
||||||
self.compile_comprehension(kind, generators)?;
|
self.compile_comprehension(kind, generators)?;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue