Skip to content

Commit ba71122

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

File tree

7 files changed

+83
-331
lines changed

7 files changed

+83
-331
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/RustPython/Parser.git", rev = "fdec727f8068c882f99a47f0439572a71fd98b28" }
33+
rustpython-parser-core = { git = "https://github.com/RustPython/Parser.git", rev = "fdec727f8068c882f99a47f0439572a71fd98b28" }
34+
rustpython-parser = { git = "https://github.com/RustPython/Parser.git", rev = "fdec727f8068c882f99a47f0439572a71fd98b28" }
35+
rustpython-ast = { git = "https://github.com/RustPython/Parser.git", rev = "fdec727f8068c882f99a47f0439572a71fd98b28" }
36+
rustpython-format = { git = "https://github.com/RustPython/Parser.git", rev = "fdec727f8068c882f99a47f0439572a71fd98b28" }
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

+15-13
Original file line numberDiff line numberDiff line change
@@ -927,31 +927,30 @@ impl Compiler {
927927
name: &str,
928928
args: &located_ast::Arguments,
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
}
@@ -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

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

602-
fn scan_parameters(&mut self, parameters: &[ast::located::Arg]) -> SymbolTableResult {
602+
fn scan_parameters(
603+
&mut self,
604+
parameters: &[ast::located::ArgWithDefault],
605+
) -> SymbolTableResult {
603606
for parameter in parameters {
604-
self.scan_parameter(parameter)?;
607+
let usage = if parameter.def.annotation.is_some() {
608+
SymbolUsage::AnnotationParameter
609+
} else {
610+
SymbolUsage::Parameter
611+
};
612+
self.register_name(parameter.def.arg.as_str(), usage, parameter.def.location())?;
605613
}
606614
Ok(())
607615
}
@@ -615,23 +623,6 @@ impl SymbolTableBuilder {
615623
self.register_name(parameter.arg.as_str(), usage, parameter.location())
616624
}
617625

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-
635626
fn scan_annotation(&mut self, annotation: &ast::located::Expr) -> SymbolTableResult {
636627
if self.future_annotations {
637628
Ok(())
@@ -1201,20 +1192,31 @@ impl SymbolTableBuilder {
12011192
line_number: LineNumber,
12021193
) -> SymbolTableResult {
12031194
// 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)?;
1195+
for default in args
1196+
.posonlyargs
1197+
.iter()
1198+
.chain(args.args.iter())
1199+
.chain(args.kwonlyargs.iter())
1200+
.filter_map(|arg| arg.default.as_ref())
1201+
{
1202+
self.scan_expression(default, ExpressionContext::Load)?; // not ExprContext?
12071203
}
12081204

12091205
// 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)?;
1206+
for annotation in args
1207+
.posonlyargs
1208+
.iter()
1209+
.chain(args.args.iter())
1210+
.chain(args.kwonlyargs.iter())
1211+
.filter_map(|arg| arg.def.annotation.as_ref())
1212+
{
1213+
self.scan_annotation(annotation)?;
12151214
}
1216-
if let Some(name) = &args.kwarg {
1217-
self.scan_parameter_annotation(name)?;
1215+
if let Some(annotation) = args.vararg.as_ref().and_then(|arg| arg.annotation.as_ref()) {
1216+
self.scan_annotation(annotation)?;
1217+
}
1218+
if let Some(annotation) = args.kwarg.as_ref().and_then(|arg| arg.annotation.as_ref()) {
1219+
self.scan_annotation(annotation)?;
12181220
}
12191221

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

compiler/src/lib.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use rustpython_codegen::{compile, symboltable};
2-
use rustpython_parser::ast::{fold::Fold, ConstantOptimizer};
2+
use rustpython_parser::ast::{self as ast, fold::Fold, ConstantOptimizer};
33

44
pub use rustpython_codegen::compile::CompileOpts;
55
pub use rustpython_compiler_core::{bytecode::CodeObject, Mode};
6-
pub use rustpython_parser::source_code::SourceLocator;
6+
pub use rustpython_parser::{source_code::SourceLocator, Parse};
77

88
// these modules are out of repository. re-exporting them here for convenience.
99
pub use rustpython_codegen as codegen;
@@ -75,13 +75,13 @@ pub fn compile_symtable(
7575
let res = match mode {
7676
Mode::Exec | Mode::Single | Mode::BlockExpr => {
7777
let ast =
78-
parser::parse_program(source, source_path).map_err(|e| locator.locate_error(e))?;
78+
ast::Suite::parse(source, source_path).map_err(|e| locator.locate_error(e))?;
7979
let ast = locator.fold(ast).unwrap();
8080
symboltable::SymbolTable::scan_program(&ast)
8181
}
8282
Mode::Eval => {
83-
let expr = parser::parse_expression(source, source_path)
84-
.map_err(|e| locator.locate_error(e))?;
83+
let expr =
84+
ast::Expr::parse(source, source_path).map_err(|e| locator.locate_error(e))?;
8585
let expr = locator.fold(expr).unwrap();
8686
symboltable::SymbolTable::scan_expr(&expr)
8787
}

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::Arguments {
317+
fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef {
318+
self.into_python_arguments().ast_to_object(vm)
319+
}
320+
fn ast_from_object(vm: &VirtualMachine, object: PyObjectRef) -> PyResult<Self> {
321+
ast::located::PythonArguments::ast_from_object(vm, object)
322+
.map(ast::located::PythonArguments::into_arguments)
323+
}
324+
}
325+
320326
#[cfg(feature = "rustpython-parser")]
321327
pub(crate) fn parse(
322328
vm: &VirtualMachine,

0 commit comments

Comments
 (0)