Skip to content

Commit 44bfc2a

Browse files
committed
new ast layout for arguments
1 parent ff70557 commit 44bfc2a

File tree

6 files changed

+75
-326
lines changed

6 files changed

+75
-326
lines changed

Cargo.lock

+14-14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+5-5
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ rustpython-pylib = { path = "pylib" }
2929
rustpython-stdlib = { path = "stdlib" }
3030
rustpython-doc = { git = "https://github.com/RustPython/__doc__", branch = "main" }
3131

32-
rustpython-literal = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec" }
33-
rustpython-parser-core = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec" }
34-
rustpython-parser = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec" }
35-
rustpython-ast = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec" }
36-
rustpython-format = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "fc301ab1b0f5483f2b2d3e28d8d92a2845b99fec" }
32+
rustpython-literal = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "72d53a0edd9be065d05feaa60b3cedae6a90b988" }
33+
rustpython-parser-core = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "72d53a0edd9be065d05feaa60b3cedae6a90b988" }
34+
rustpython-parser = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "72d53a0edd9be065d05feaa60b3cedae6a90b988" }
35+
rustpython-ast = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "72d53a0edd9be065d05feaa60b3cedae6a90b988" }
36+
rustpython-format = { git = "https://github.com/youknowone/RustPython-Parser.git", rev = "72d53a0edd9be065d05feaa60b3cedae6a90b988" }
3737
# rustpython-literal = { path = "../RustPython-parser/literal" }
3838
# rustpython-parser-core = { path = "../RustPython-parser/core" }
3939
# rustpython-parser = { path = "../RustPython-parser/parser" }

compiler/codegen/src/compile.rs

+17-15
Original file line numberDiff line numberDiff line change
@@ -925,33 +925,32 @@ impl Compiler {
925925
fn enter_function(
926926
&mut self,
927927
name: &str,
928-
args: &located_ast::Arguments,
928+
args: &located_ast::FunctionArguments,
929929
) -> CompileResult<bytecode::MakeFunctionFlags> {
930-
let have_defaults = !args.defaults.is_empty();
930+
let defaults: Vec<_> = args.defaults().collect();
931+
let have_defaults = !defaults.is_empty();
931932
if have_defaults {
932933
// Construct a tuple:
933-
let size = args.defaults.len().to_u32();
934-
for element in &args.defaults {
934+
let size = defaults.len().to_u32();
935+
for element in &defaults {
935936
self.compile_expression(element)?;
936937
}
937938
emit!(self, Instruction::BuildTuple { size });
938939
}
939940

940-
if !args.kw_defaults.is_empty() {
941-
let required_kw_count = args.kwonlyargs.len().saturating_sub(args.kw_defaults.len());
942-
for (kw, default) in args.kwonlyargs[required_kw_count..]
943-
.iter()
944-
.zip(&args.kw_defaults)
945-
{
941+
let (kw_without_defaults, kw_with_defaults) = args.split_kwonlyargs();
942+
if !kw_with_defaults.is_empty() {
943+
let default_kw_count = kw_with_defaults.len();
944+
for (arg, default) in kw_with_defaults.iter() {
946945
self.emit_constant(ConstantData::Str {
947-
value: kw.arg.to_string(),
946+
value: arg.arg.to_string(),
948947
});
949948
self.compile_expression(default)?;
950949
}
951950
emit!(
952951
self,
953952
Instruction::BuildMap {
954-
size: args.kw_defaults.len().to_u32(),
953+
size: default_kw_count.to_u32(),
955954
}
956955
);
957956
}
@@ -960,7 +959,7 @@ impl Compiler {
960959
if have_defaults {
961960
func_flags |= bytecode::MakeFunctionFlags::DEFAULTS;
962961
}
963-
if !args.kw_defaults.is_empty() {
962+
if !kw_with_defaults.is_empty() {
964963
func_flags |= bytecode::MakeFunctionFlags::KW_ONLY_DEFAULTS;
965964
}
966965

@@ -975,7 +974,9 @@ impl Compiler {
975974
let args_iter = std::iter::empty()
976975
.chain(&args.posonlyargs)
977976
.chain(&args.args)
978-
.chain(&args.kwonlyargs);
977+
.map(|arg| arg.as_arg())
978+
.chain(kw_without_defaults.into_iter())
979+
.chain(kw_with_defaults.into_iter().map(|(arg, _)| arg));
979980
for name in args_iter {
980981
self.varname(name.arg.as_str())?;
981982
}
@@ -1155,7 +1156,7 @@ impl Compiler {
11551156
fn compile_function_def(
11561157
&mut self,
11571158
name: &str,
1158-
args: &located_ast::Arguments,
1159+
args: &located_ast::FunctionArguments,
11591160
body: &[located_ast::Stmt],
11601161
decorator_list: &[located_ast::Expr],
11611162
returns: Option<&located_ast::Expr>, // TODO: use type hint somehow..
@@ -1228,6 +1229,7 @@ impl Compiler {
12281229
.chain(&args.posonlyargs)
12291230
.chain(&args.args)
12301231
.chain(&args.kwonlyargs)
1232+
.map(|arg| arg.as_arg())
12311233
.chain(args.vararg.as_deref())
12321234
.chain(args.kwarg.as_deref());
12331235
for arg in args_iter {

compiler/codegen/src/symboltable.rs

+29-30
Original file line numberDiff line numberDiff line change
@@ -599,9 +599,14 @@ impl SymbolTableBuilder {
599599
Ok(())
600600
}
601601

602-
fn scan_parameters(&mut self, parameters: &[ast::located::Arg]) -> SymbolTableResult {
602+
fn scan_parameters(&mut self, parameters: &[ast::located::FunctionArg]) -> SymbolTableResult {
603603
for parameter in parameters {
604-
self.scan_parameter(parameter)?;
604+
let usage = if parameter.annotation.is_some() {
605+
SymbolUsage::AnnotationParameter
606+
} else {
607+
SymbolUsage::Parameter
608+
};
609+
self.register_name(parameter.arg.as_str(), usage, parameter.location())?;
605610
}
606611
Ok(())
607612
}
@@ -615,23 +620,6 @@ impl SymbolTableBuilder {
615620
self.register_name(parameter.arg.as_str(), usage, parameter.location())
616621
}
617622

618-
fn scan_parameters_annotations(
619-
&mut self,
620-
parameters: &[ast::located::Arg],
621-
) -> SymbolTableResult {
622-
for parameter in parameters {
623-
self.scan_parameter_annotation(parameter)?;
624-
}
625-
Ok(())
626-
}
627-
628-
fn scan_parameter_annotation(&mut self, parameter: &ast::located::Arg) -> SymbolTableResult {
629-
if let Some(annotation) = &parameter.annotation {
630-
self.scan_annotation(annotation)?;
631-
}
632-
Ok(())
633-
}
634-
635623
fn scan_annotation(&mut self, annotation: &ast::located::Expr) -> SymbolTableResult {
636624
if self.future_annotations {
637625
Ok(())
@@ -1197,24 +1185,35 @@ impl SymbolTableBuilder {
11971185
fn enter_function(
11981186
&mut self,
11991187
name: &str,
1200-
args: &ast::located::Arguments,
1188+
args: &ast::located::FunctionArguments,
12011189
line_number: LineNumber,
12021190
) -> SymbolTableResult {
12031191
// Evaluate eventual default parameters:
1204-
self.scan_expressions(&args.defaults, ExpressionContext::Load)?;
1205-
for expression in args.kw_defaults.iter() {
1206-
self.scan_expression(expression, ExpressionContext::Load)?;
1192+
for default in args
1193+
.posonlyargs
1194+
.iter()
1195+
.chain(args.args.iter())
1196+
.chain(args.kwonlyargs.iter())
1197+
.filter_map(|arg| arg.default.as_ref())
1198+
{
1199+
self.scan_expression(default, ExpressionContext::Load)?; // not ExprContext?
12071200
}
12081201

12091202
// Annotations are scanned in outer scope:
1210-
self.scan_parameters_annotations(&args.posonlyargs)?;
1211-
self.scan_parameters_annotations(&args.args)?;
1212-
self.scan_parameters_annotations(&args.kwonlyargs)?;
1213-
if let Some(name) = &args.vararg {
1214-
self.scan_parameter_annotation(name)?;
1203+
for annotation in args
1204+
.posonlyargs
1205+
.iter()
1206+
.chain(args.args.iter())
1207+
.chain(args.kwonlyargs.iter())
1208+
.filter_map(|arg| arg.annotation.as_ref())
1209+
{
1210+
self.scan_annotation(annotation)?;
12151211
}
1216-
if let Some(name) = &args.kwarg {
1217-
self.scan_parameter_annotation(name)?;
1212+
if let Some(annotation) = args.vararg.as_ref().and_then(|arg| arg.annotation.as_ref()) {
1213+
self.scan_annotation(annotation)?;
1214+
}
1215+
if let Some(annotation) = args.kwarg.as_ref().and_then(|arg| arg.annotation.as_ref()) {
1216+
self.scan_annotation(annotation)?;
12181217
}
12191218

12201219
self.enter_scope(name, SymbolTableType::Function, line_number.get());

vm/src/stdlib/ast.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,6 @@ trait Node: Sized {
9999
fn ast_from_object(vm: &VirtualMachine, object: PyObjectRef) -> PyResult<Self>;
100100
}
101101

102-
trait NamedNode: Node {
103-
const NAME: &'static str;
104-
}
105-
106102
impl<T: Node> Node for Vec<T> {
107103
fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef {
108104
vm.ctx
@@ -317,6 +313,16 @@ impl Node for ast::ConversionFlag {
317313
}
318314
}
319315

316+
impl Node for ast::located::FunctionArguments {
317+
fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef {
318+
self.into_arguments().ast_to_object(vm)
319+
}
320+
fn ast_from_object(vm: &VirtualMachine, object: PyObjectRef) -> PyResult<Self> {
321+
ast::located::Arguments::ast_from_object(vm, object)
322+
.map(ast::located::Arguments::into_function_arguments)
323+
}
324+
}
325+
320326
#[cfg(feature = "rustpython-parser")]
321327
pub(crate) fn parse(
322328
vm: &VirtualMachine,

0 commit comments

Comments
 (0)