mirror of
https://github.com/RustPython/Parser.git
synced 2025-07-22 12:35:22 +00:00
Implement new features for updated python asdl
This commit is contained in:
parent
308c82a935
commit
266b1f1aea
3 changed files with 52 additions and 40 deletions
|
@ -680,6 +680,7 @@ impl Compiler {
|
||||||
orelse,
|
orelse,
|
||||||
..
|
..
|
||||||
} => self.compile_for(target, iter, body, orelse, true)?,
|
} => self.compile_for(target, iter, body, orelse, true)?,
|
||||||
|
Match { subject, cases } => self.compile_match(subject, cases)?,
|
||||||
Raise { exc, cause } => {
|
Raise { exc, cause } => {
|
||||||
let kind = match exc {
|
let kind = match exc {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
|
@ -881,17 +882,19 @@ impl Compiler {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut num_kw_only_defaults = 0;
|
if !args.kw_defaults.is_empty() {
|
||||||
for (kw, default) in args.kwonlyargs.iter().zip(&args.kw_defaults) {
|
let required_kw_count = args.kwonlyargs.len().saturating_sub(args.kw_defaults.len());
|
||||||
|
for (kw, default) in args.kwonlyargs[required_kw_count..]
|
||||||
|
.iter()
|
||||||
|
.zip(&args.kw_defaults)
|
||||||
|
{
|
||||||
self.emit_constant(ConstantData::Str {
|
self.emit_constant(ConstantData::Str {
|
||||||
value: kw.node.arg.clone(),
|
value: kw.node.arg.clone(),
|
||||||
});
|
});
|
||||||
self.compile_expression(default)?;
|
self.compile_expression(default)?;
|
||||||
num_kw_only_defaults += 1;
|
|
||||||
}
|
}
|
||||||
if num_kw_only_defaults > 0 {
|
|
||||||
self.emit(Instruction::BuildMap {
|
self.emit(Instruction::BuildMap {
|
||||||
size: num_kw_only_defaults,
|
size: args.kw_defaults.len() as u32,
|
||||||
unpack: false,
|
unpack: false,
|
||||||
for_call: false,
|
for_call: false,
|
||||||
});
|
});
|
||||||
|
@ -901,7 +904,7 @@ impl Compiler {
|
||||||
if have_defaults {
|
if have_defaults {
|
||||||
funcflags |= bytecode::MakeFunctionFlags::DEFAULTS;
|
funcflags |= bytecode::MakeFunctionFlags::DEFAULTS;
|
||||||
}
|
}
|
||||||
if num_kw_only_defaults > 0 {
|
if !args.kw_defaults.is_empty() {
|
||||||
funcflags |= bytecode::MakeFunctionFlags::KW_ONLY_DEFAULTS;
|
funcflags |= bytecode::MakeFunctionFlags::KW_ONLY_DEFAULTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1519,6 +1522,16 @@ impl Compiler {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compile_match(
|
||||||
|
&mut self,
|
||||||
|
subject: &ast::Expr,
|
||||||
|
cases: &[ast::MatchCase],
|
||||||
|
) -> CompileResult<()> {
|
||||||
|
eprintln!("match subject: {subject:?}");
|
||||||
|
eprintln!("match cases: {cases:?}");
|
||||||
|
Err(self.error(CompileErrorType::NotImplementedYet))
|
||||||
|
}
|
||||||
|
|
||||||
fn compile_chained_comparison(
|
fn compile_chained_comparison(
|
||||||
&mut self,
|
&mut self,
|
||||||
left: &ast::Expr,
|
left: &ast::Expr,
|
||||||
|
@ -1928,11 +1941,7 @@ impl Compiler {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_dict(
|
fn compile_dict(&mut self, keys: &[ast::Expr], values: &[ast::Expr]) -> CompileResult<()> {
|
||||||
&mut self,
|
|
||||||
keys: &[ast::Expr],
|
|
||||||
values: &[ast::Expr],
|
|
||||||
) -> CompileResult<()> {
|
|
||||||
let mut size = 0;
|
let mut size = 0;
|
||||||
|
|
||||||
let (packed_values, unpacked_values) = values.split_at(keys.len());
|
let (packed_values, unpacked_values) = values.split_at(keys.len());
|
||||||
|
@ -2099,7 +2108,7 @@ impl Compiler {
|
||||||
};
|
};
|
||||||
self.compile_expression(value)?;
|
self.compile_expression(value)?;
|
||||||
self.emit(Instruction::FormatValue {
|
self.emit(Instruction::FormatValue {
|
||||||
conversion: compile_conversion_flag(*conversion),
|
conversion: (*conversion).try_into().expect("invalid conversion flag"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Name { id, .. } => self.load_name(id)?,
|
Name { id, .. } => self.load_name(id)?,
|
||||||
|
@ -2454,7 +2463,7 @@ impl Compiler {
|
||||||
|
|
||||||
let mut loop_labels = vec![];
|
let mut loop_labels = vec![];
|
||||||
for generator in generators {
|
for generator in generators {
|
||||||
if generator.is_async {
|
if generator.is_async > 0 {
|
||||||
unimplemented!("async for comprehensions");
|
unimplemented!("async for comprehensions");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2543,7 +2552,7 @@ impl Compiler {
|
||||||
return Err(self.error(CompileErrorType::InvalidFuturePlacement));
|
return Err(self.error(CompileErrorType::InvalidFuturePlacement));
|
||||||
}
|
}
|
||||||
for feature in features {
|
for feature in features {
|
||||||
match &*feature.name {
|
match &*feature.node.name {
|
||||||
// Python 3 features; we've already implemented them by default
|
// Python 3 features; we've already implemented them by default
|
||||||
"nested_scopes" | "generators" | "division" | "absolute_import"
|
"nested_scopes" | "generators" | "division" | "absolute_import"
|
||||||
| "with_statement" | "print_function" | "unicode_literals" => {}
|
| "with_statement" | "print_function" | "unicode_literals" => {}
|
||||||
|
@ -2667,17 +2676,6 @@ fn compile_location(location: &ast::Location) -> bytecode::Location {
|
||||||
bytecode::Location::new(location.row(), location.column())
|
bytecode::Location::new(location.row(), location.column())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_conversion_flag(
|
|
||||||
conversion_flag: Option<ast::ConversionFlag>,
|
|
||||||
) -> bytecode::ConversionFlag {
|
|
||||||
match conversion_flag {
|
|
||||||
None => bytecode::ConversionFlag::None,
|
|
||||||
Some(ast::ConversionFlag::Ascii) => bytecode::ConversionFlag::Ascii,
|
|
||||||
Some(ast::ConversionFlag::Repr) => bytecode::ConversionFlag::Repr,
|
|
||||||
Some(ast::ConversionFlag::Str) => bytecode::ConversionFlag::Str,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compile_constant(value: &ast::Constant) -> ConstantData {
|
fn compile_constant(value: &ast::Constant) -> ConstantData {
|
||||||
match value {
|
match value {
|
||||||
ast::Constant::None => ConstantData::None,
|
ast::Constant::None => ConstantData::None,
|
||||||
|
|
|
@ -37,6 +37,7 @@ pub enum CompileErrorType {
|
||||||
TooManyStarUnpack,
|
TooManyStarUnpack,
|
||||||
EmptyWithItems,
|
EmptyWithItems,
|
||||||
EmptyWithBody,
|
EmptyWithBody,
|
||||||
|
NotImplementedYet, // RustPython marker for unimplemented features
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for CompileErrorType {
|
impl fmt::Display for CompileErrorType {
|
||||||
|
@ -78,6 +79,9 @@ impl fmt::Display for CompileErrorType {
|
||||||
CompileErrorType::EmptyWithBody => {
|
CompileErrorType::EmptyWithBody => {
|
||||||
write!(f, "empty body on With")
|
write!(f, "empty body on With")
|
||||||
}
|
}
|
||||||
|
CompileErrorType::NotImplementedYet => {
|
||||||
|
write!(f, "RustPython does not implement this feature yet")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -639,7 +639,7 @@ impl SymbolTableBuilder {
|
||||||
if let ImportFrom { module, names, .. } = &statement.node {
|
if let ImportFrom { module, names, .. } = &statement.node {
|
||||||
if module.as_deref() == Some("__future__") {
|
if module.as_deref() == Some("__future__") {
|
||||||
for feature in names {
|
for feature in names {
|
||||||
if feature.name == "annotations" {
|
if feature.node.name == "annotations" {
|
||||||
self.future_annotations = true;
|
self.future_annotations = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -739,13 +739,13 @@ impl SymbolTableBuilder {
|
||||||
}
|
}
|
||||||
Import { names } | ImportFrom { names, .. } => {
|
Import { names } | ImportFrom { names, .. } => {
|
||||||
for name in names {
|
for name in names {
|
||||||
if let Some(alias) = &name.asname {
|
if let Some(alias) = &name.node.asname {
|
||||||
// `import mymodule as myalias`
|
// `import mymodule as myalias`
|
||||||
self.register_name(alias, SymbolUsage::Imported, location)?;
|
self.register_name(alias, SymbolUsage::Imported, location)?;
|
||||||
} else {
|
} else {
|
||||||
// `import module`
|
// `import module`
|
||||||
self.register_name(
|
self.register_name(
|
||||||
name.name.split('.').next().unwrap(),
|
name.node.name.split('.').next().unwrap(),
|
||||||
SymbolUsage::Imported,
|
SymbolUsage::Imported,
|
||||||
location,
|
location,
|
||||||
)?;
|
)?;
|
||||||
|
@ -782,7 +782,7 @@ impl SymbolTableBuilder {
|
||||||
} => {
|
} => {
|
||||||
// https://github.com/python/cpython/blob/main/Python/symtable.c#L1233
|
// https://github.com/python/cpython/blob/main/Python/symtable.c#L1233
|
||||||
match &target.node {
|
match &target.node {
|
||||||
ast::ExprKind::Name { id, .. } if *simple => {
|
ast::ExprKind::Name { id, .. } if *simple > 0 => {
|
||||||
self.register_name(id, SymbolUsage::AnnotationAssigned, location)?;
|
self.register_name(id, SymbolUsage::AnnotationAssigned, location)?;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -823,6 +823,15 @@ impl SymbolTableBuilder {
|
||||||
self.scan_statements(orelse)?;
|
self.scan_statements(orelse)?;
|
||||||
self.scan_statements(finalbody)?;
|
self.scan_statements(finalbody)?;
|
||||||
}
|
}
|
||||||
|
Match {
|
||||||
|
subject: _,
|
||||||
|
cases: _,
|
||||||
|
} => {
|
||||||
|
return Err(SymbolTableError {
|
||||||
|
error: "match expression is not implemented yet".to_owned(),
|
||||||
|
location: Location::default(),
|
||||||
|
});
|
||||||
|
}
|
||||||
Raise { exc, cause } => {
|
Raise { exc, cause } => {
|
||||||
if let Some(expression) = exc {
|
if let Some(expression) = exc {
|
||||||
self.scan_expression(expression, ExpressionContext::Load)?;
|
self.scan_expression(expression, ExpressionContext::Load)?;
|
||||||
|
@ -875,12 +884,13 @@ impl SymbolTableBuilder {
|
||||||
self.scan_expression(value, ExpressionContext::Load)?;
|
self.scan_expression(value, ExpressionContext::Load)?;
|
||||||
}
|
}
|
||||||
Dict { keys, values } => {
|
Dict { keys, values } => {
|
||||||
for (key, value) in keys.iter().zip(values) {
|
let (packed, unpacked) = values.split_at(keys.len());
|
||||||
if let Some(key) = key {
|
for (key, value) in keys.iter().zip(packed) {
|
||||||
self.scan_expression(key, context)?;
|
self.scan_expression(key, context)?;
|
||||||
} else {
|
self.scan_expression(value, context)?;
|
||||||
// dict unpacking marker
|
|
||||||
}
|
}
|
||||||
|
for value in unpacked {
|
||||||
|
// dict unpacking marker
|
||||||
self.scan_expression(value, context)?;
|
self.scan_expression(value, context)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue