mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Refactor ast to hold data as seperated type
This commit is contained in:
8
Cargo.lock
generated
8
Cargo.lock
generated
@@ -1967,7 +1967,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-ast"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/RustPython/Parser.git?rev=48920a034e93ae7c737129ea427c068dc30e2da5#48920a034e93ae7c737129ea427c068dc30e2da5"
|
||||
source = "git+https://github.com/RustPython/Parser.git?rev=7b8844bd3e470d6b835147ecb445202130ec18d8#7b8844bd3e470d6b835147ecb445202130ec18d8"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"rustpython-compiler-core",
|
||||
@@ -2027,7 +2027,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-compiler-core"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/RustPython/Parser.git?rev=48920a034e93ae7c737129ea427c068dc30e2da5#48920a034e93ae7c737129ea427c068dc30e2da5"
|
||||
source = "git+https://github.com/RustPython/Parser.git?rev=7b8844bd3e470d6b835147ecb445202130ec18d8#7b8844bd3e470d6b835147ecb445202130ec18d8"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bstr",
|
||||
@@ -2089,7 +2089,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-literal"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/RustPython/Parser.git?rev=48920a034e93ae7c737129ea427c068dc30e2da5#48920a034e93ae7c737129ea427c068dc30e2da5"
|
||||
source = "git+https://github.com/RustPython/Parser.git?rev=7b8844bd3e470d6b835147ecb445202130ec18d8#7b8844bd3e470d6b835147ecb445202130ec18d8"
|
||||
dependencies = [
|
||||
"hexf-parse",
|
||||
"lexical-parse-float",
|
||||
@@ -2100,7 +2100,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-parser"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/RustPython/Parser.git?rev=48920a034e93ae7c737129ea427c068dc30e2da5#48920a034e93ae7c737129ea427c068dc30e2da5"
|
||||
source = "git+https://github.com/RustPython/Parser.git?rev=7b8844bd3e470d6b835147ecb445202130ec18d8#7b8844bd3e470d6b835147ecb445202130ec18d8"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
|
||||
@@ -17,10 +17,10 @@ members = [
|
||||
]
|
||||
|
||||
[workspace.dependencies]
|
||||
rustpython-literal = { git = "https://github.com/RustPython/Parser.git", rev = "48920a034e93ae7c737129ea427c068dc30e2da5" }
|
||||
rustpython-compiler-core = { git = "https://github.com/RustPython/Parser.git", rev = "48920a034e93ae7c737129ea427c068dc30e2da5" }
|
||||
rustpython-parser = { git = "https://github.com/RustPython/Parser.git", rev = "48920a034e93ae7c737129ea427c068dc30e2da5" }
|
||||
rustpython-ast = { git = "https://github.com/RustPython/Parser.git", rev = "48920a034e93ae7c737129ea427c068dc30e2da5" }
|
||||
rustpython-literal = { git = "https://github.com/RustPython/Parser.git", rev = "7b8844bd3e470d6b835147ecb445202130ec18d8" }
|
||||
rustpython-compiler-core = { git = "https://github.com/RustPython/Parser.git", rev = "7b8844bd3e470d6b835147ecb445202130ec18d8" }
|
||||
rustpython-parser = { git = "https://github.com/RustPython/Parser.git", rev = "7b8844bd3e470d6b835147ecb445202130ec18d8" }
|
||||
rustpython-ast = { git = "https://github.com/RustPython/Parser.git", rev = "7b8844bd3e470d6b835147ecb445202130ec18d8" }
|
||||
# rustpython-literal = { path = "../RustPython-parser/literal" }
|
||||
# rustpython-compiler-core = { path = "../RustPython-parser/core" }
|
||||
# rustpython-parser = { path = "../RustPython-parser/parser" }
|
||||
|
||||
@@ -96,13 +96,15 @@ pub fn compile_top(
|
||||
opts: CompileOpts,
|
||||
) -> CompileResult<CodeObject> {
|
||||
match ast {
|
||||
ast::Mod::Module { body, .. } => compile_program(body, source_path, opts),
|
||||
ast::Mod::Interactive { body } => match mode {
|
||||
ast::Mod::Module(ast::ModModule { body, .. }) => compile_program(body, source_path, opts),
|
||||
ast::Mod::Interactive(ast::ModInteractive { 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(ast::ModExpression { body }) => {
|
||||
compile_expression(body, source_path, opts)
|
||||
}
|
||||
ast::Mod::FunctionType { .. } => panic!("can't compile a FunctionType"),
|
||||
}
|
||||
}
|
||||
@@ -376,7 +378,7 @@ impl Compiler {
|
||||
|
||||
if let Some((last, body)) = body.split_last() {
|
||||
for statement in body {
|
||||
if let ast::StmtKind::Expr { value } = &statement.node {
|
||||
if let ast::StmtKind::Expr(ast::StmtExpr { value }) = &statement.node {
|
||||
self.compile_expression(value)?;
|
||||
emit!(self, Instruction::PrintExpr);
|
||||
} else {
|
||||
@@ -384,7 +386,7 @@ impl Compiler {
|
||||
}
|
||||
}
|
||||
|
||||
if let ast::StmtKind::Expr { value } = &last.node {
|
||||
if let ast::StmtKind::Expr(ast::StmtExpr { value }) = &last.node {
|
||||
self.compile_expression(value)?;
|
||||
emit!(self, Instruction::Duplicate);
|
||||
emit!(self, Instruction::PrintExpr);
|
||||
@@ -555,12 +557,14 @@ impl Compiler {
|
||||
fn compile_statement(&mut self, statement: &ast::Stmt) -> CompileResult<()> {
|
||||
trace!("Compiling {:?}", statement);
|
||||
self.set_source_location(statement.start());
|
||||
use ast::StmtKind::*;
|
||||
use ast::{StmtKind::*, *};
|
||||
|
||||
match &statement.node {
|
||||
// we do this here because `from __future__` still executes that `from` statement at runtime,
|
||||
// we still need to compile the ImportFrom down below
|
||||
ImportFrom { module, names, .. } if module.as_deref() == Some("__future__") => {
|
||||
ImportFrom(ast::StmtImportFrom { module, names, .. })
|
||||
if module.as_deref() == Some("__future__") =>
|
||||
{
|
||||
self.compile_future_features(names)?
|
||||
}
|
||||
// if we find any other statement, stop accepting future statements
|
||||
@@ -568,7 +572,7 @@ impl Compiler {
|
||||
}
|
||||
|
||||
match &statement.node {
|
||||
Import { names } => {
|
||||
Import(StmtImport { names }) => {
|
||||
// import a, b, c as d
|
||||
for name in names {
|
||||
let name = &name.node;
|
||||
@@ -589,11 +593,11 @@ impl Compiler {
|
||||
}
|
||||
}
|
||||
}
|
||||
ImportFrom {
|
||||
ImportFrom(StmtImportFrom {
|
||||
level,
|
||||
module,
|
||||
names,
|
||||
} => {
|
||||
}) => {
|
||||
let import_star = names.iter().any(|n| n.node.name == "*");
|
||||
|
||||
let from_list = if import_star {
|
||||
@@ -653,16 +657,16 @@ impl Compiler {
|
||||
emit!(self, Instruction::Pop);
|
||||
}
|
||||
}
|
||||
Expr { value } => {
|
||||
Expr(StmtExpr { value }) => {
|
||||
self.compile_expression(value)?;
|
||||
|
||||
// Pop result of stack, since we not use it:
|
||||
emit!(self, Instruction::Pop);
|
||||
}
|
||||
Global { .. } | Nonlocal { .. } => {
|
||||
Global(StmtGlobal { .. }) | Nonlocal(StmtNonlocal { .. }) => {
|
||||
// Handled during symbol table construction.
|
||||
}
|
||||
If { test, body, orelse } => {
|
||||
If(StmtIf { test, body, orelse }) => {
|
||||
let after_block = self.new_block();
|
||||
if orelse.is_empty() {
|
||||
// Only if:
|
||||
@@ -686,25 +690,25 @@ impl Compiler {
|
||||
}
|
||||
self.switch_to_block(after_block);
|
||||
}
|
||||
While { test, body, orelse } => self.compile_while(test, body, orelse)?,
|
||||
With { items, body, .. } => self.compile_with(items, body, false)?,
|
||||
AsyncWith { items, body, .. } => self.compile_with(items, body, true)?,
|
||||
For {
|
||||
While(StmtWhile { test, body, orelse }) => self.compile_while(test, body, orelse)?,
|
||||
With(StmtWith { items, body, .. }) => self.compile_with(items, body, false)?,
|
||||
AsyncWith(StmtAsyncWith { items, body, .. }) => self.compile_with(items, body, true)?,
|
||||
For(StmtFor {
|
||||
target,
|
||||
iter,
|
||||
body,
|
||||
orelse,
|
||||
..
|
||||
} => self.compile_for(target, iter, body, orelse, false)?,
|
||||
AsyncFor {
|
||||
}) => self.compile_for(target, iter, body, orelse, false)?,
|
||||
AsyncFor(StmtAsyncFor {
|
||||
target,
|
||||
iter,
|
||||
body,
|
||||
orelse,
|
||||
..
|
||||
} => self.compile_for(target, iter, body, orelse, true)?,
|
||||
Match { subject, cases } => self.compile_match(subject, cases)?,
|
||||
Raise { exc, cause } => {
|
||||
}) => self.compile_for(target, iter, body, orelse, true)?,
|
||||
Match(StmtMatch { subject, cases }) => self.compile_match(subject, cases)?,
|
||||
Raise(StmtRaise { exc, cause }) => {
|
||||
let kind = match exc {
|
||||
Some(value) => {
|
||||
self.compile_expression(value)?;
|
||||
@@ -720,26 +724,26 @@ impl Compiler {
|
||||
};
|
||||
emit!(self, Instruction::Raise { kind });
|
||||
}
|
||||
Try {
|
||||
Try(StmtTry {
|
||||
body,
|
||||
handlers,
|
||||
orelse,
|
||||
finalbody,
|
||||
} => self.compile_try_statement(body, handlers, orelse, finalbody)?,
|
||||
TryStar {
|
||||
}) => self.compile_try_statement(body, handlers, orelse, finalbody)?,
|
||||
TryStar(StmtTryStar {
|
||||
body,
|
||||
handlers,
|
||||
orelse,
|
||||
finalbody,
|
||||
} => self.compile_try_star_statement(body, handlers, orelse, finalbody)?,
|
||||
FunctionDef {
|
||||
}) => self.compile_try_star_statement(body, handlers, orelse, finalbody)?,
|
||||
FunctionDef(StmtFunctionDef {
|
||||
name,
|
||||
args,
|
||||
body,
|
||||
decorator_list,
|
||||
returns,
|
||||
..
|
||||
} => self.compile_function_def(
|
||||
}) => self.compile_function_def(
|
||||
name,
|
||||
args,
|
||||
body,
|
||||
@@ -747,14 +751,14 @@ impl Compiler {
|
||||
returns.as_deref(),
|
||||
false,
|
||||
)?,
|
||||
AsyncFunctionDef {
|
||||
AsyncFunctionDef(StmtAsyncFunctionDef {
|
||||
name,
|
||||
args,
|
||||
body,
|
||||
decorator_list,
|
||||
returns,
|
||||
..
|
||||
} => self.compile_function_def(
|
||||
}) => self.compile_function_def(
|
||||
name,
|
||||
args,
|
||||
body,
|
||||
@@ -762,14 +766,14 @@ impl Compiler {
|
||||
returns.as_deref(),
|
||||
true,
|
||||
)?,
|
||||
ClassDef {
|
||||
ClassDef(StmtClassDef {
|
||||
name,
|
||||
body,
|
||||
bases,
|
||||
keywords,
|
||||
decorator_list,
|
||||
} => self.compile_class_def(name, body, bases, keywords, decorator_list)?,
|
||||
Assert { test, msg } => {
|
||||
}) => self.compile_class_def(name, body, bases, keywords, decorator_list)?,
|
||||
Assert(StmtAssert { test, msg }) => {
|
||||
// if some flag, ignore all assert statements!
|
||||
if self.opts.optimize == 0 {
|
||||
let after_block = self.new_block();
|
||||
@@ -814,7 +818,7 @@ impl Compiler {
|
||||
);
|
||||
}
|
||||
},
|
||||
Return { value } => {
|
||||
Return(StmtReturn { value }) => {
|
||||
if !self.ctx.in_func() {
|
||||
return Err(self.error_loc(CodegenErrorType::InvalidReturn, statement.start()));
|
||||
}
|
||||
@@ -838,7 +842,7 @@ impl Compiler {
|
||||
|
||||
emit!(self, Instruction::ReturnValue);
|
||||
}
|
||||
Assign { targets, value, .. } => {
|
||||
Assign(StmtAssign { targets, value, .. }) => {
|
||||
self.compile_expression(value)?;
|
||||
|
||||
for (i, target) in targets.iter().enumerate() {
|
||||
@@ -848,14 +852,16 @@ impl Compiler {
|
||||
self.compile_store(target)?;
|
||||
}
|
||||
}
|
||||
AugAssign { target, op, value } => self.compile_augassign(target, op, value)?,
|
||||
AnnAssign {
|
||||
AugAssign(StmtAugAssign { target, op, value }) => {
|
||||
self.compile_augassign(target, op, value)?
|
||||
}
|
||||
AnnAssign(StmtAnnAssign {
|
||||
target,
|
||||
annotation,
|
||||
value,
|
||||
..
|
||||
} => self.compile_annotated_assign(target, annotation, value.as_deref())?,
|
||||
Delete { targets } => {
|
||||
}) => self.compile_annotated_assign(target, annotation, value.as_deref())?,
|
||||
Delete(StmtDelete { targets }) => {
|
||||
for target in targets {
|
||||
self.compile_delete(target)?;
|
||||
}
|
||||
@@ -869,24 +875,28 @@ impl Compiler {
|
||||
|
||||
fn compile_delete(&mut self, expression: &ast::Expr) -> CompileResult<()> {
|
||||
match &expression.node {
|
||||
ast::ExprKind::Name { id, .. } => self.compile_name(id, NameUsage::Delete)?,
|
||||
ast::ExprKind::Attribute { value, attr, .. } => {
|
||||
ast::ExprKind::Name(ast::ExprName { id, .. }) => {
|
||||
self.compile_name(id, NameUsage::Delete)?
|
||||
}
|
||||
ast::ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) => {
|
||||
self.check_forbidden_name(attr, NameUsage::Delete)?;
|
||||
self.compile_expression(value)?;
|
||||
let idx = self.name(attr);
|
||||
emit!(self, Instruction::DeleteAttr { idx });
|
||||
}
|
||||
ast::ExprKind::Subscript { value, slice, .. } => {
|
||||
ast::ExprKind::Subscript(ast::ExprSubscript { value, slice, .. }) => {
|
||||
self.compile_expression(value)?;
|
||||
self.compile_expression(slice)?;
|
||||
emit!(self, Instruction::DeleteSubscript);
|
||||
}
|
||||
ast::ExprKind::Tuple { elts, .. } | ast::ExprKind::List { elts, .. } => {
|
||||
ast::ExprKind::Tuple(ast::ExprTuple { elts, .. })
|
||||
| ast::ExprKind::List(ast::ExprList { elts, .. }) => {
|
||||
for element in elts {
|
||||
self.compile_delete(element)?;
|
||||
}
|
||||
}
|
||||
ast::ExprKind::BinOp { .. } | ast::ExprKind::UnaryOp { .. } => {
|
||||
ast::ExprKind::BinOp(ast::ExprBinOp { .. })
|
||||
| ast::ExprKind::UnaryOp(ast::ExprUnaryOp { .. }) => {
|
||||
return Err(self.error(CodegenErrorType::Delete("expression")))
|
||||
}
|
||||
_ => return Err(self.error(CodegenErrorType::Delete(expression.node.name()))),
|
||||
@@ -1015,7 +1025,11 @@ impl Compiler {
|
||||
self.switch_to_block(handler_block);
|
||||
// Exception is on top of stack now
|
||||
for handler in handlers {
|
||||
let ast::ExcepthandlerKind::ExceptHandler { type_, name, body } = &handler.node;
|
||||
let ast::ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
||||
type_,
|
||||
name,
|
||||
body,
|
||||
}) = &handler.node;
|
||||
let next_handler = self.new_block();
|
||||
|
||||
// If we gave a typ,
|
||||
@@ -1287,16 +1301,22 @@ impl Compiler {
|
||||
for statement in body {
|
||||
let res = match &statement.node {
|
||||
AnnAssign { .. } => true,
|
||||
For { body, orelse, .. } => Self::find_ann(body) || Self::find_ann(orelse),
|
||||
If { body, orelse, .. } => Self::find_ann(body) || Self::find_ann(orelse),
|
||||
While { body, orelse, .. } => Self::find_ann(body) || Self::find_ann(orelse),
|
||||
With { body, .. } => Self::find_ann(body),
|
||||
Try {
|
||||
For(ast::StmtFor { body, orelse, .. }) => {
|
||||
Self::find_ann(body) || Self::find_ann(orelse)
|
||||
}
|
||||
If(ast::StmtIf { body, orelse, .. }) => {
|
||||
Self::find_ann(body) || Self::find_ann(orelse)
|
||||
}
|
||||
While(ast::StmtWhile { body, orelse, .. }) => {
|
||||
Self::find_ann(body) || Self::find_ann(orelse)
|
||||
}
|
||||
With(ast::StmtWith { body, .. }) => Self::find_ann(body),
|
||||
Try(ast::StmtTry {
|
||||
body,
|
||||
orelse,
|
||||
finalbody,
|
||||
..
|
||||
} => Self::find_ann(body) || Self::find_ann(orelse) || Self::find_ann(finalbody),
|
||||
}) => Self::find_ann(body) || Self::find_ann(orelse) || Self::find_ann(finalbody),
|
||||
_ => false,
|
||||
};
|
||||
if res {
|
||||
@@ -1716,7 +1736,7 @@ impl Compiler {
|
||||
// Compile annotation:
|
||||
self.compile_annotation(annotation)?;
|
||||
|
||||
if let ast::ExprKind::Name { id, .. } = &target.node {
|
||||
if let ast::ExprKind::Name(ast::ExprName { id, .. }) = &target.node {
|
||||
// Store as dict entry in __annotations__ dict:
|
||||
let annotations = self.name("__annotations__");
|
||||
emit!(self, Instruction::LoadNameAny(annotations));
|
||||
@@ -1734,19 +1754,20 @@ impl Compiler {
|
||||
|
||||
fn compile_store(&mut self, target: &ast::Expr) -> CompileResult<()> {
|
||||
match &target.node {
|
||||
ast::ExprKind::Name { id, .. } => self.store_name(id)?,
|
||||
ast::ExprKind::Subscript { value, slice, .. } => {
|
||||
ast::ExprKind::Name(ast::ExprName { id, .. }) => self.store_name(id)?,
|
||||
ast::ExprKind::Subscript(ast::ExprSubscript { value, slice, .. }) => {
|
||||
self.compile_expression(value)?;
|
||||
self.compile_expression(slice)?;
|
||||
emit!(self, Instruction::StoreSubscript);
|
||||
}
|
||||
ast::ExprKind::Attribute { value, attr, .. } => {
|
||||
ast::ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) => {
|
||||
self.check_forbidden_name(attr, NameUsage::Store)?;
|
||||
self.compile_expression(value)?;
|
||||
let idx = self.name(attr);
|
||||
emit!(self, Instruction::StoreAttr { idx });
|
||||
}
|
||||
ast::ExprKind::List { elts, .. } | ast::ExprKind::Tuple { elts, .. } => {
|
||||
ast::ExprKind::List(ast::ExprList { elts, .. })
|
||||
| ast::ExprKind::Tuple(ast::ExprTuple { elts, .. }) => {
|
||||
let mut seen_star = false;
|
||||
|
||||
// Scan for star args:
|
||||
@@ -1781,7 +1802,7 @@ impl Compiler {
|
||||
}
|
||||
|
||||
for element in elts {
|
||||
if let ast::ExprKind::Starred { value, .. } = &element.node {
|
||||
if let ast::ExprKind::Starred(ast::ExprStarred { value, .. }) = &element.node {
|
||||
self.compile_store(value)?;
|
||||
} else {
|
||||
self.compile_store(element)?;
|
||||
@@ -1814,18 +1835,18 @@ impl Compiler {
|
||||
}
|
||||
|
||||
let kind = match &target.node {
|
||||
ast::ExprKind::Name { id, .. } => {
|
||||
ast::ExprKind::Name(ast::ExprName { id, .. }) => {
|
||||
self.compile_name(id, NameUsage::Load)?;
|
||||
AugAssignKind::Name { id }
|
||||
}
|
||||
ast::ExprKind::Subscript { value, slice, .. } => {
|
||||
ast::ExprKind::Subscript(ast::ExprSubscript { value, slice, .. }) => {
|
||||
self.compile_expression(value)?;
|
||||
self.compile_expression(slice)?;
|
||||
emit!(self, Instruction::Duplicate2);
|
||||
emit!(self, Instruction::Subscript);
|
||||
AugAssignKind::Subscript
|
||||
}
|
||||
ast::ExprKind::Attribute { value, attr, .. } => {
|
||||
ast::ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) => {
|
||||
self.check_forbidden_name(attr, NameUsage::Store)?;
|
||||
self.compile_expression(value)?;
|
||||
emit!(self, Instruction::Duplicate);
|
||||
@@ -1900,7 +1921,7 @@ impl Compiler {
|
||||
) -> CompileResult<()> {
|
||||
// Compile expression for test, and jump to label if false
|
||||
match &expression.node {
|
||||
ast::ExprKind::BoolOp { op, values } => {
|
||||
ast::ExprKind::BoolOp(ast::ExprBoolOp { op, values }) => {
|
||||
match op {
|
||||
ast::Boolop::And => {
|
||||
if condition {
|
||||
@@ -1946,10 +1967,10 @@ impl Compiler {
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::ExprKind::UnaryOp {
|
||||
ast::ExprKind::UnaryOp(ast::ExprUnaryOp {
|
||||
op: ast::Unaryop::Not,
|
||||
operand,
|
||||
} => {
|
||||
}) => {
|
||||
self.compile_jump_if(operand, !condition, target_block)?;
|
||||
}
|
||||
_ => {
|
||||
@@ -2041,25 +2062,25 @@ impl Compiler {
|
||||
|
||||
use ast::ExprKind::*;
|
||||
match &expression.node {
|
||||
Call {
|
||||
Call(ast::ExprCall {
|
||||
func,
|
||||
args,
|
||||
keywords,
|
||||
} => self.compile_call(func, args, keywords)?,
|
||||
BoolOp { op, values } => self.compile_bool_op(op, values)?,
|
||||
BinOp { left, op, right } => {
|
||||
}) => self.compile_call(func, args, keywords)?,
|
||||
BoolOp(ast::ExprBoolOp { op, values }) => self.compile_bool_op(op, values)?,
|
||||
BinOp(ast::ExprBinOp { left, op, right }) => {
|
||||
self.compile_expression(left)?;
|
||||
self.compile_expression(right)?;
|
||||
|
||||
// Perform operation:
|
||||
self.compile_op(op, false);
|
||||
}
|
||||
Subscript { value, slice, .. } => {
|
||||
Subscript(ast::ExprSubscript { value, slice, .. }) => {
|
||||
self.compile_expression(value)?;
|
||||
self.compile_expression(slice)?;
|
||||
emit!(self, Instruction::Subscript);
|
||||
}
|
||||
UnaryOp { op, operand } => {
|
||||
UnaryOp(ast::ExprUnaryOp { op, operand }) => {
|
||||
self.compile_expression(operand)?;
|
||||
|
||||
// Perform operation:
|
||||
@@ -2071,22 +2092,22 @@ impl Compiler {
|
||||
};
|
||||
emit!(self, Instruction::UnaryOperation { op });
|
||||
}
|
||||
Attribute { value, attr, .. } => {
|
||||
Attribute(ast::ExprAttribute { value, attr, .. }) => {
|
||||
self.compile_expression(value)?;
|
||||
let idx = self.name(attr);
|
||||
emit!(self, Instruction::LoadAttr { idx });
|
||||
}
|
||||
Compare {
|
||||
Compare(ast::ExprCompare {
|
||||
left,
|
||||
ops,
|
||||
comparators,
|
||||
} => {
|
||||
}) => {
|
||||
self.compile_chained_comparison(left, ops, comparators)?;
|
||||
}
|
||||
Constant { value, .. } => {
|
||||
Constant(ast::ExprConstant { value, .. }) => {
|
||||
self.emit_constant(compile_constant(value));
|
||||
}
|
||||
List { elts, .. } => {
|
||||
List(ast::ExprList { elts, .. }) => {
|
||||
let (size, unpack) = self.gather_elements(0, elts)?;
|
||||
if unpack {
|
||||
emit!(self, Instruction::BuildListUnpack { size });
|
||||
@@ -2094,7 +2115,7 @@ impl Compiler {
|
||||
emit!(self, Instruction::BuildList { size });
|
||||
}
|
||||
}
|
||||
Tuple { elts, .. } => {
|
||||
Tuple(ast::ExprTuple { elts, .. }) => {
|
||||
let (size, unpack) = self.gather_elements(0, elts)?;
|
||||
if unpack {
|
||||
emit!(self, Instruction::BuildTupleUnpack { size });
|
||||
@@ -2102,7 +2123,7 @@ impl Compiler {
|
||||
emit!(self, Instruction::BuildTuple { size });
|
||||
}
|
||||
}
|
||||
Set { elts, .. } => {
|
||||
Set(ast::ExprSet { elts, .. }) => {
|
||||
let (size, unpack) = self.gather_elements(0, elts)?;
|
||||
if unpack {
|
||||
emit!(self, Instruction::BuildSetUnpack { size });
|
||||
@@ -2110,10 +2131,10 @@ impl Compiler {
|
||||
emit!(self, Instruction::BuildSet { size });
|
||||
}
|
||||
}
|
||||
Dict { keys, values } => {
|
||||
Dict(ast::ExprDict { keys, values }) => {
|
||||
self.compile_dict(keys, values)?;
|
||||
}
|
||||
Slice { lower, upper, step } => {
|
||||
Slice(ast::ExprSlice { lower, upper, step }) => {
|
||||
let mut compile_bound = |bound: Option<&ast::Expr>| match bound {
|
||||
Some(exp) => self.compile_expression(exp),
|
||||
None => {
|
||||
@@ -2129,7 +2150,7 @@ impl Compiler {
|
||||
let step = step.is_some();
|
||||
emit!(self, Instruction::BuildSlice { step });
|
||||
}
|
||||
Yield { value } => {
|
||||
Yield(ast::ExprYield { value }) => {
|
||||
if !self.ctx.in_func() {
|
||||
return Err(self.error(CodegenErrorType::InvalidYield));
|
||||
}
|
||||
@@ -2140,7 +2161,7 @@ impl Compiler {
|
||||
};
|
||||
emit!(self, Instruction::YieldValue);
|
||||
}
|
||||
Await { value } => {
|
||||
Await(ast::ExprAwait { value }) => {
|
||||
if self.ctx.func != FunctionContext::AsyncFunction {
|
||||
return Err(self.error(CodegenErrorType::InvalidAwait));
|
||||
}
|
||||
@@ -2149,7 +2170,7 @@ impl Compiler {
|
||||
self.emit_constant(ConstantData::None);
|
||||
emit!(self, Instruction::YieldFrom);
|
||||
}
|
||||
YieldFrom { value } => {
|
||||
YieldFrom(ast::ExprYieldFrom { value }) => {
|
||||
match self.ctx.func {
|
||||
FunctionContext::NoFunction => {
|
||||
return Err(self.error(CodegenErrorType::InvalidYieldFrom));
|
||||
@@ -2165,7 +2186,7 @@ impl Compiler {
|
||||
self.emit_constant(ConstantData::None);
|
||||
emit!(self, Instruction::YieldFrom);
|
||||
}
|
||||
ast::ExprKind::JoinedStr { values } => {
|
||||
ast::ExprKind::JoinedStr(ast::ExprJoinedStr { values }) => {
|
||||
if let Some(value) = try_get_constant_string(values) {
|
||||
self.emit_constant(ConstantData::Str { value })
|
||||
} else {
|
||||
@@ -2180,11 +2201,11 @@ impl Compiler {
|
||||
)
|
||||
}
|
||||
}
|
||||
ast::ExprKind::FormattedValue {
|
||||
ast::ExprKind::FormattedValue(ast::ExprFormattedValue {
|
||||
value,
|
||||
conversion,
|
||||
format_spec,
|
||||
} => {
|
||||
}) => {
|
||||
match format_spec {
|
||||
Some(spec) => self.compile_expression(spec)?,
|
||||
None => self.emit_constant(ConstantData::Str {
|
||||
@@ -2200,8 +2221,8 @@ impl Compiler {
|
||||
},
|
||||
);
|
||||
}
|
||||
Name { id, .. } => self.load_name(id)?,
|
||||
Lambda { args, body } => {
|
||||
Name(ast::ExprName { id, .. }) => self.load_name(id)?,
|
||||
Lambda(ast::ExprLambda { args, body }) => {
|
||||
let prev_ctx = self.ctx;
|
||||
|
||||
let name = "<lambda>".to_owned();
|
||||
@@ -2232,7 +2253,7 @@ impl Compiler {
|
||||
|
||||
self.ctx = prev_ctx;
|
||||
}
|
||||
ListComp { elt, generators } => {
|
||||
ListComp(ast::ExprListComp { elt, generators }) => {
|
||||
self.compile_comprehension(
|
||||
"<listcomp>",
|
||||
Some(Instruction::BuildList {
|
||||
@@ -2251,7 +2272,7 @@ impl Compiler {
|
||||
},
|
||||
)?;
|
||||
}
|
||||
SetComp { elt, generators } => {
|
||||
SetComp(ast::ExprSetComp { elt, generators }) => {
|
||||
self.compile_comprehension(
|
||||
"<setcomp>",
|
||||
Some(Instruction::BuildSet {
|
||||
@@ -2270,11 +2291,11 @@ impl Compiler {
|
||||
},
|
||||
)?;
|
||||
}
|
||||
DictComp {
|
||||
DictComp(ast::ExprDictComp {
|
||||
key,
|
||||
value,
|
||||
generators,
|
||||
} => {
|
||||
}) => {
|
||||
self.compile_comprehension(
|
||||
"<dictcomp>",
|
||||
Some(Instruction::BuildMap {
|
||||
@@ -2297,7 +2318,7 @@ impl Compiler {
|
||||
},
|
||||
)?;
|
||||
}
|
||||
GeneratorExp { elt, generators } => {
|
||||
GeneratorExp(ast::ExprGeneratorExp { elt, generators }) => {
|
||||
self.compile_comprehension("<genexpr>", None, generators, &|compiler| {
|
||||
compiler.compile_comprehension_element(elt)?;
|
||||
compiler.mark_generator();
|
||||
@@ -2307,10 +2328,10 @@ impl Compiler {
|
||||
Ok(())
|
||||
})?;
|
||||
}
|
||||
Starred { .. } => {
|
||||
Starred(ast::ExprStarred { .. }) => {
|
||||
return Err(self.error(CodegenErrorType::InvalidStarExpr));
|
||||
}
|
||||
IfExp { test, body, orelse } => {
|
||||
IfExp(ast::ExprIfExp { test, body, orelse }) => {
|
||||
let else_block = self.new_block();
|
||||
let after_block = self.new_block();
|
||||
self.compile_jump_if(test, false, else_block)?;
|
||||
@@ -2332,7 +2353,7 @@ impl Compiler {
|
||||
self.switch_to_block(after_block);
|
||||
}
|
||||
|
||||
NamedExpr { target, value } => {
|
||||
NamedExpr(ast::ExprNamedExpr { target, value }) => {
|
||||
self.compile_expression(value)?;
|
||||
emit!(self, Instruction::Duplicate);
|
||||
self.compile_store(target)?;
|
||||
@@ -2377,15 +2398,16 @@ impl Compiler {
|
||||
args: &[ast::Expr],
|
||||
keywords: &[ast::Keyword],
|
||||
) -> CompileResult<()> {
|
||||
let method = if let ast::ExprKind::Attribute { value, attr, .. } = &func.node {
|
||||
self.compile_expression(value)?;
|
||||
let idx = self.name(attr);
|
||||
emit!(self, Instruction::LoadMethod { idx });
|
||||
true
|
||||
} else {
|
||||
self.compile_expression(func)?;
|
||||
false
|
||||
};
|
||||
let method =
|
||||
if let ast::ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) = &func.node {
|
||||
self.compile_expression(value)?;
|
||||
let idx = self.name(attr);
|
||||
emit!(self, Instruction::LoadMethod { idx });
|
||||
true
|
||||
} else {
|
||||
self.compile_expression(func)?;
|
||||
false
|
||||
};
|
||||
let call = self.compile_call_inner(0, args, keywords)?;
|
||||
if method {
|
||||
self.compile_method_call(call)
|
||||
@@ -2494,7 +2516,7 @@ impl Compiler {
|
||||
let groups = elements
|
||||
.iter()
|
||||
.map(|element| {
|
||||
if let ast::ExprKind::Starred { value, .. } = &element.node {
|
||||
if let ast::ExprKind::Starred(ast::ExprStarred { value, .. }) = &element.node {
|
||||
(true, value.as_ref())
|
||||
} else {
|
||||
(false, element)
|
||||
@@ -2791,7 +2813,7 @@ impl EmitArg<bytecode::Label> for ir::BlockIdx {
|
||||
|
||||
fn split_doc(body: &[ast::Stmt]) -> (Option<String>, &[ast::Stmt]) {
|
||||
if let Some((val, body_rest)) = body.split_first() {
|
||||
if let ast::StmtKind::Expr { value } = &val.node {
|
||||
if let ast::StmtKind::Expr(ast::StmtExpr { value }) = &val.node {
|
||||
if let Some(doc) = try_get_constant_string(std::slice::from_ref(value)) {
|
||||
return (Some(doc), body_rest);
|
||||
}
|
||||
@@ -2803,14 +2825,14 @@ fn split_doc(body: &[ast::Stmt]) -> (Option<String>, &[ast::Stmt]) {
|
||||
fn try_get_constant_string(values: &[ast::Expr]) -> Option<String> {
|
||||
fn get_constant_string_inner(out_string: &mut String, value: &ast::Expr) -> bool {
|
||||
match &value.node {
|
||||
ast::ExprKind::Constant {
|
||||
ast::ExprKind::Constant(ast::ExprConstant {
|
||||
value: ast::Constant::Str(s),
|
||||
..
|
||||
} => {
|
||||
}) => {
|
||||
out_string.push_str(s);
|
||||
true
|
||||
}
|
||||
ast::ExprKind::JoinedStr { values } => values
|
||||
ast::ExprKind::JoinedStr(ast::ExprJoinedStr { values }) => values
|
||||
.iter()
|
||||
.all(|value| get_constant_string_inner(out_string, value)),
|
||||
_ => false,
|
||||
|
||||
@@ -634,9 +634,9 @@ impl SymbolTableBuilder {
|
||||
}
|
||||
|
||||
fn scan_statement(&mut self, statement: &ast::Stmt) -> SymbolTableResult {
|
||||
use ast::StmtKind::*;
|
||||
use ast::{StmtKind::*, *};
|
||||
let location = statement.start();
|
||||
if let ImportFrom { module, names, .. } = &statement.node {
|
||||
if let ImportFrom(StmtImportFrom { module, names, .. }) = &statement.node {
|
||||
if module.as_deref() == Some("__future__") {
|
||||
for feature in names {
|
||||
if feature.node.name == "annotations" {
|
||||
@@ -646,32 +646,32 @@ impl SymbolTableBuilder {
|
||||
}
|
||||
}
|
||||
match &statement.node {
|
||||
Global { names } => {
|
||||
Global(StmtGlobal { names }) => {
|
||||
for name in names {
|
||||
self.register_name(name, SymbolUsage::Global, location)?;
|
||||
}
|
||||
}
|
||||
Nonlocal { names } => {
|
||||
Nonlocal(StmtNonlocal { names }) => {
|
||||
for name in names {
|
||||
self.register_name(name, SymbolUsage::Nonlocal, location)?;
|
||||
}
|
||||
}
|
||||
FunctionDef {
|
||||
FunctionDef(StmtFunctionDef {
|
||||
name,
|
||||
body,
|
||||
args,
|
||||
decorator_list,
|
||||
returns,
|
||||
..
|
||||
}
|
||||
| AsyncFunctionDef {
|
||||
})
|
||||
| AsyncFunctionDef(StmtAsyncFunctionDef {
|
||||
name,
|
||||
body,
|
||||
args,
|
||||
decorator_list,
|
||||
returns,
|
||||
..
|
||||
} => {
|
||||
}) => {
|
||||
self.scan_expressions(decorator_list, ExpressionContext::Load)?;
|
||||
self.register_name(name, SymbolUsage::Assigned, location)?;
|
||||
if let Some(expression) = returns {
|
||||
@@ -681,13 +681,13 @@ impl SymbolTableBuilder {
|
||||
self.scan_statements(body)?;
|
||||
self.leave_scope();
|
||||
}
|
||||
ClassDef {
|
||||
ClassDef(StmtClassDef {
|
||||
name,
|
||||
body,
|
||||
bases,
|
||||
keywords,
|
||||
decorator_list,
|
||||
} => {
|
||||
}) => {
|
||||
self.enter_scope(name, SymbolTableType::Class, location.row());
|
||||
let prev_class = std::mem::replace(&mut self.class_name, Some(name.to_owned()));
|
||||
self.register_name("__module__", SymbolUsage::Assigned, location)?;
|
||||
@@ -704,32 +704,32 @@ impl SymbolTableBuilder {
|
||||
self.scan_expressions(decorator_list, ExpressionContext::Load)?;
|
||||
self.register_name(name, SymbolUsage::Assigned, location)?;
|
||||
}
|
||||
Expr { value } => self.scan_expression(value, ExpressionContext::Load)?,
|
||||
If { test, body, orelse } => {
|
||||
Expr(StmtExpr { value }) => self.scan_expression(value, ExpressionContext::Load)?,
|
||||
If(StmtIf { test, body, orelse }) => {
|
||||
self.scan_expression(test, ExpressionContext::Load)?;
|
||||
self.scan_statements(body)?;
|
||||
self.scan_statements(orelse)?;
|
||||
}
|
||||
For {
|
||||
For(StmtFor {
|
||||
target,
|
||||
iter,
|
||||
body,
|
||||
orelse,
|
||||
..
|
||||
}
|
||||
| AsyncFor {
|
||||
})
|
||||
| AsyncFor(StmtAsyncFor {
|
||||
target,
|
||||
iter,
|
||||
body,
|
||||
orelse,
|
||||
..
|
||||
} => {
|
||||
}) => {
|
||||
self.scan_expression(target, ExpressionContext::Store)?;
|
||||
self.scan_expression(iter, ExpressionContext::Load)?;
|
||||
self.scan_statements(body)?;
|
||||
self.scan_statements(orelse)?;
|
||||
}
|
||||
While { test, body, orelse } => {
|
||||
While(StmtWhile { test, body, orelse }) => {
|
||||
self.scan_expression(test, ExpressionContext::Load)?;
|
||||
self.scan_statements(body)?;
|
||||
self.scan_statements(orelse)?;
|
||||
@@ -737,7 +737,7 @@ impl SymbolTableBuilder {
|
||||
Break | Continue | Pass => {
|
||||
// No symbols here.
|
||||
}
|
||||
Import { names } | ImportFrom { names, .. } => {
|
||||
Import(StmtImport { names }) | ImportFrom(StmtImportFrom { names, .. }) => {
|
||||
for name in names {
|
||||
if let Some(alias) = &name.node.asname {
|
||||
// `import my_module as my_alias`
|
||||
@@ -752,37 +752,37 @@ impl SymbolTableBuilder {
|
||||
}
|
||||
}
|
||||
}
|
||||
Return { value } => {
|
||||
Return(StmtReturn { value }) => {
|
||||
if let Some(expression) = value {
|
||||
self.scan_expression(expression, ExpressionContext::Load)?;
|
||||
}
|
||||
}
|
||||
Assert { test, msg } => {
|
||||
Assert(StmtAssert { test, msg }) => {
|
||||
self.scan_expression(test, ExpressionContext::Load)?;
|
||||
if let Some(expression) = msg {
|
||||
self.scan_expression(expression, ExpressionContext::Load)?;
|
||||
}
|
||||
}
|
||||
Delete { targets } => {
|
||||
Delete(StmtDelete { targets }) => {
|
||||
self.scan_expressions(targets, ExpressionContext::Delete)?;
|
||||
}
|
||||
Assign { targets, value, .. } => {
|
||||
Assign(StmtAssign { targets, value, .. }) => {
|
||||
self.scan_expressions(targets, ExpressionContext::Store)?;
|
||||
self.scan_expression(value, ExpressionContext::Load)?;
|
||||
}
|
||||
AugAssign { target, value, .. } => {
|
||||
AugAssign(StmtAugAssign { target, value, .. }) => {
|
||||
self.scan_expression(target, ExpressionContext::Store)?;
|
||||
self.scan_expression(value, ExpressionContext::Load)?;
|
||||
}
|
||||
AnnAssign {
|
||||
AnnAssign(StmtAnnAssign {
|
||||
target,
|
||||
annotation,
|
||||
value,
|
||||
simple,
|
||||
} => {
|
||||
}) => {
|
||||
// https://github.com/python/cpython/blob/main/Python/symtable.c#L1233
|
||||
match &target.node {
|
||||
ast::ExprKind::Name { id, .. } if *simple > 0 => {
|
||||
ast::ExprKind::Name(ast::ExprName { id, .. }) if *simple > 0 => {
|
||||
self.register_name(id, SymbolUsage::AnnotationAssigned, location)?;
|
||||
}
|
||||
_ => {
|
||||
@@ -794,7 +794,7 @@ impl SymbolTableBuilder {
|
||||
self.scan_expression(value, ExpressionContext::Load)?;
|
||||
}
|
||||
}
|
||||
With { items, body, .. } | AsyncWith { items, body, .. } => {
|
||||
With(StmtWith { items, body, .. }) | AsyncWith(StmtAsyncWith { items, body, .. }) => {
|
||||
for item in items {
|
||||
self.scan_expression(&item.context_expr, ExpressionContext::Load)?;
|
||||
if let Some(expression) = &item.optional_vars {
|
||||
@@ -803,21 +803,25 @@ impl SymbolTableBuilder {
|
||||
}
|
||||
self.scan_statements(body)?;
|
||||
}
|
||||
Try {
|
||||
Try(StmtTry {
|
||||
body,
|
||||
handlers,
|
||||
orelse,
|
||||
finalbody,
|
||||
}
|
||||
| TryStar {
|
||||
})
|
||||
| TryStar(StmtTryStar {
|
||||
body,
|
||||
handlers,
|
||||
orelse,
|
||||
finalbody,
|
||||
} => {
|
||||
}) => {
|
||||
self.scan_statements(body)?;
|
||||
for handler in handlers {
|
||||
let ast::ExcepthandlerKind::ExceptHandler { type_, name, body } = &handler.node;
|
||||
let ast::ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
||||
type_,
|
||||
name,
|
||||
body,
|
||||
}) = &handler.node;
|
||||
if let Some(expression) = type_ {
|
||||
self.scan_expression(expression, ExpressionContext::Load)?;
|
||||
}
|
||||
@@ -829,16 +833,16 @@ impl SymbolTableBuilder {
|
||||
self.scan_statements(orelse)?;
|
||||
self.scan_statements(finalbody)?;
|
||||
}
|
||||
Match {
|
||||
Match(StmtMatch {
|
||||
subject: _,
|
||||
cases: _,
|
||||
} => {
|
||||
}) => {
|
||||
return Err(SymbolTableError {
|
||||
error: "match expression is not implemented yet".to_owned(),
|
||||
location: Location::default(),
|
||||
});
|
||||
}
|
||||
Raise { exc, cause } => {
|
||||
Raise(StmtRaise { exc, cause }) => {
|
||||
if let Some(expression) = exc {
|
||||
self.scan_expression(expression, ExpressionContext::Load)?;
|
||||
}
|
||||
@@ -866,30 +870,30 @@ impl SymbolTableBuilder {
|
||||
expression: &ast::Expr,
|
||||
context: ExpressionContext,
|
||||
) -> SymbolTableResult {
|
||||
use ast::ExprKind::*;
|
||||
use ast::{ExprKind::*, *};
|
||||
let location = expression.start();
|
||||
match &expression.node {
|
||||
BinOp { left, right, .. } => {
|
||||
BinOp(ExprBinOp { left, right, .. }) => {
|
||||
self.scan_expression(left, context)?;
|
||||
self.scan_expression(right, context)?;
|
||||
}
|
||||
BoolOp { values, .. } => {
|
||||
BoolOp(ExprBoolOp { values, .. }) => {
|
||||
self.scan_expressions(values, context)?;
|
||||
}
|
||||
Compare {
|
||||
Compare(ExprCompare {
|
||||
left, comparators, ..
|
||||
} => {
|
||||
}) => {
|
||||
self.scan_expression(left, context)?;
|
||||
self.scan_expressions(comparators, context)?;
|
||||
}
|
||||
Subscript { value, slice, .. } => {
|
||||
Subscript(ExprSubscript { value, slice, .. }) => {
|
||||
self.scan_expression(value, ExpressionContext::Load)?;
|
||||
self.scan_expression(slice, ExpressionContext::Load)?;
|
||||
}
|
||||
Attribute { value, .. } => {
|
||||
Attribute(ExprAttribute { value, .. }) => {
|
||||
self.scan_expression(value, ExpressionContext::Load)?;
|
||||
}
|
||||
Dict { keys, values } => {
|
||||
Dict(ExprDict { keys, values }) => {
|
||||
for (key, value) in keys.iter().zip(values.iter()) {
|
||||
if let Some(key) = key {
|
||||
self.scan_expression(key, context)?;
|
||||
@@ -897,28 +901,30 @@ impl SymbolTableBuilder {
|
||||
self.scan_expression(value, context)?;
|
||||
}
|
||||
}
|
||||
Await { value } => {
|
||||
Await(ExprAwait { value }) => {
|
||||
self.scan_expression(value, context)?;
|
||||
}
|
||||
Yield { value } => {
|
||||
Yield(ExprYield { value }) => {
|
||||
if let Some(expression) = value {
|
||||
self.scan_expression(expression, context)?;
|
||||
}
|
||||
}
|
||||
YieldFrom { value } => {
|
||||
YieldFrom(ExprYieldFrom { value }) => {
|
||||
self.scan_expression(value, context)?;
|
||||
}
|
||||
UnaryOp { operand, .. } => {
|
||||
UnaryOp(ExprUnaryOp { operand, .. }) => {
|
||||
self.scan_expression(operand, context)?;
|
||||
}
|
||||
Constant { .. } => {}
|
||||
Starred { value, .. } => {
|
||||
Constant(ExprConstant { .. }) => {}
|
||||
Starred(ExprStarred { value, .. }) => {
|
||||
self.scan_expression(value, context)?;
|
||||
}
|
||||
Tuple { elts, .. } | Set { elts, .. } | List { elts, .. } => {
|
||||
Tuple(ExprTuple { elts, .. })
|
||||
| Set(ExprSet { elts, .. })
|
||||
| List(ExprList { elts, .. }) => {
|
||||
self.scan_expressions(elts, context)?;
|
||||
}
|
||||
Slice { lower, upper, step } => {
|
||||
Slice(ExprSlice { lower, upper, step }) => {
|
||||
if let Some(lower) = lower {
|
||||
self.scan_expression(lower, context)?;
|
||||
}
|
||||
@@ -929,27 +935,27 @@ impl SymbolTableBuilder {
|
||||
self.scan_expression(step, context)?;
|
||||
}
|
||||
}
|
||||
GeneratorExp { elt, generators } => {
|
||||
GeneratorExp(ExprGeneratorExp { elt, generators }) => {
|
||||
self.scan_comprehension("genexpr", elt, None, generators, location)?;
|
||||
}
|
||||
ListComp { elt, generators } => {
|
||||
ListComp(ExprListComp { elt, generators }) => {
|
||||
self.scan_comprehension("genexpr", elt, None, generators, location)?;
|
||||
}
|
||||
SetComp { elt, generators } => {
|
||||
SetComp(ExprSetComp { elt, generators }) => {
|
||||
self.scan_comprehension("genexpr", elt, None, generators, location)?;
|
||||
}
|
||||
DictComp {
|
||||
DictComp(ExprDictComp {
|
||||
key,
|
||||
value,
|
||||
generators,
|
||||
} => {
|
||||
}) => {
|
||||
self.scan_comprehension("genexpr", key, Some(value), generators, location)?;
|
||||
}
|
||||
Call {
|
||||
Call(ExprCall {
|
||||
func,
|
||||
args,
|
||||
keywords,
|
||||
} => {
|
||||
}) => {
|
||||
match context {
|
||||
ExpressionContext::IterDefinitionExp => {
|
||||
self.scan_expression(func, ExpressionContext::IterDefinitionExp)?;
|
||||
@@ -964,20 +970,20 @@ impl SymbolTableBuilder {
|
||||
self.scan_expression(&keyword.node.value, ExpressionContext::Load)?;
|
||||
}
|
||||
}
|
||||
FormattedValue {
|
||||
FormattedValue(ExprFormattedValue {
|
||||
value, format_spec, ..
|
||||
} => {
|
||||
}) => {
|
||||
self.scan_expression(value, ExpressionContext::Load)?;
|
||||
if let Some(spec) = format_spec {
|
||||
self.scan_expression(spec, ExpressionContext::Load)?;
|
||||
}
|
||||
}
|
||||
JoinedStr { values } => {
|
||||
JoinedStr(ExprJoinedStr { values }) => {
|
||||
for value in values {
|
||||
self.scan_expression(value, ExpressionContext::Load)?;
|
||||
}
|
||||
}
|
||||
Name { id, .. } => {
|
||||
Name(ExprName { id, .. }) => {
|
||||
// Determine the contextual usage of this symbol:
|
||||
match context {
|
||||
ExpressionContext::Delete => {
|
||||
@@ -1003,7 +1009,7 @@ impl SymbolTableBuilder {
|
||||
self.register_name("__class__", SymbolUsage::Used, location)?;
|
||||
}
|
||||
}
|
||||
Lambda { args, body } => {
|
||||
Lambda(ExprLambda { args, body }) => {
|
||||
self.enter_function("lambda", args, expression.start().row())?;
|
||||
match context {
|
||||
ExpressionContext::IterDefinitionExp => {
|
||||
@@ -1015,13 +1021,13 @@ impl SymbolTableBuilder {
|
||||
}
|
||||
self.leave_scope();
|
||||
}
|
||||
IfExp { test, body, orelse } => {
|
||||
IfExp(ExprIfExp { test, body, orelse }) => {
|
||||
self.scan_expression(test, ExpressionContext::Load)?;
|
||||
self.scan_expression(body, ExpressionContext::Load)?;
|
||||
self.scan_expression(orelse, ExpressionContext::Load)?;
|
||||
}
|
||||
|
||||
NamedExpr { target, value } => {
|
||||
NamedExpr(ExprNamedExpr { target, value }) => {
|
||||
// named expressions are not allowed in the definition of
|
||||
// comprehension iterator definitions
|
||||
if let ExpressionContext::IterDefinitionExp = context {
|
||||
@@ -1038,7 +1044,7 @@ impl SymbolTableBuilder {
|
||||
// that are used in comprehensions. This required to correctly
|
||||
// propagate the scope of the named assigned named and not to
|
||||
// propagate inner names.
|
||||
if let Name { id, .. } = &target.node {
|
||||
if let Name(ExprName { id, .. }) = &target.node {
|
||||
let table = self.tables.last().unwrap();
|
||||
if table.typ == SymbolTableType::Comprehension {
|
||||
self.register_name(
|
||||
|
||||
570
vm/src/stdlib/ast/gen.rs
generated
570
vm/src/stdlib/ast/gen.rs
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user