mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Merge pull request #1817 from RustPython/coolreader18/location-copy
Make ast::Location implement Copy
This commit is contained in:
10 files changed
+89
-129
No files matched your search
@@ -9,7 +9,7 @@ use std::collections::{HashMap, HashSet};
|
||||
use std::fmt;
|
||||
|
||||
/// Sourcode location.
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Location {
|
||||
row: usize,
|
||||
column: usize,
|
||||
|
||||
+67
-105
@@ -19,6 +19,8 @@ use rustpython_parser::{ast, parser};
|
||||
|
||||
type BasicOutputStream = PeepholeOptimizer<CodeObjectStream>;
|
||||
|
||||
type CompileResult<T> = Result<T, CompileError>;
|
||||
|
||||
/// Main structure holding the state of compilation.
|
||||
struct Compiler<O: OutputStream = BasicOutputStream> {
|
||||
output_stack: Vec<O>,
|
||||
@@ -59,33 +61,29 @@ pub fn compile(
|
||||
mode: Mode,
|
||||
source_path: String,
|
||||
optimize: u8,
|
||||
) -> Result<CodeObject, CompileError> {
|
||||
) -> CompileResult<CodeObject> {
|
||||
match mode {
|
||||
Mode::Exec => {
|
||||
let ast = parser::parse_program(source)?;
|
||||
compile_program(ast, source_path.clone(), optimize)
|
||||
compile_program(ast, source_path, optimize)
|
||||
}
|
||||
Mode::Eval => {
|
||||
let statement = parser::parse_statement(source)?;
|
||||
compile_statement_eval(statement, source_path.clone(), optimize)
|
||||
compile_statement_eval(statement, source_path, optimize)
|
||||
}
|
||||
Mode::Single => {
|
||||
let ast = parser::parse_program(source)?;
|
||||
compile_program_single(ast, source_path.clone(), optimize)
|
||||
compile_program_single(ast, source_path, optimize)
|
||||
}
|
||||
}
|
||||
.map_err(|mut err| {
|
||||
err.update_source_path(&source_path);
|
||||
err
|
||||
})
|
||||
}
|
||||
|
||||
/// A helper function for the shared code of the different compile functions
|
||||
fn with_compiler(
|
||||
source_path: String,
|
||||
optimize: u8,
|
||||
f: impl FnOnce(&mut Compiler) -> Result<(), CompileError>,
|
||||
) -> Result<CodeObject, CompileError> {
|
||||
f: impl FnOnce(&mut Compiler) -> CompileResult<()>,
|
||||
) -> CompileResult<CodeObject> {
|
||||
let mut compiler = Compiler::new(optimize);
|
||||
compiler.source_path = Some(source_path);
|
||||
compiler.push_new_code_object("<module>".to_owned());
|
||||
@@ -100,7 +98,7 @@ pub fn compile_program(
|
||||
ast: ast::Program,
|
||||
source_path: String,
|
||||
optimize: u8,
|
||||
) -> Result<CodeObject, CompileError> {
|
||||
) -> CompileResult<CodeObject> {
|
||||
with_compiler(source_path, optimize, |compiler| {
|
||||
let symbol_table = make_symbol_table(&ast)?;
|
||||
compiler.compile_program(&ast, symbol_table)
|
||||
@@ -112,7 +110,7 @@ pub fn compile_statement_eval(
|
||||
statement: Vec<ast::Statement>,
|
||||
source_path: String,
|
||||
optimize: u8,
|
||||
) -> Result<CodeObject, CompileError> {
|
||||
) -> CompileResult<CodeObject> {
|
||||
with_compiler(source_path, optimize, |compiler| {
|
||||
let symbol_table = statements_to_symbol_table(&statement)?;
|
||||
compiler.compile_statement_eval(&statement, symbol_table)
|
||||
@@ -124,7 +122,7 @@ pub fn compile_program_single(
|
||||
ast: ast::Program,
|
||||
source_path: String,
|
||||
optimize: u8,
|
||||
) -> Result<CodeObject, CompileError> {
|
||||
) -> CompileResult<CodeObject> {
|
||||
with_compiler(source_path, optimize, |compiler| {
|
||||
let symbol_table = make_symbol_table(&ast)?;
|
||||
compiler.compile_program_single(&ast, symbol_table)
|
||||
@@ -157,6 +155,18 @@ impl<O: OutputStream> Compiler<O> {
|
||||
}
|
||||
}
|
||||
|
||||
fn error(&self, error: CompileErrorType) -> CompileError {
|
||||
self.error_loc(error, self.current_source_location)
|
||||
}
|
||||
fn error_loc(&self, error: CompileErrorType, location: ast::Location) -> CompileError {
|
||||
CompileError {
|
||||
error,
|
||||
location,
|
||||
source_path: self.source_path.clone(),
|
||||
statement: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn push_output(&mut self, code: CodeObject) {
|
||||
self.output_stack.push(code.into());
|
||||
}
|
||||
@@ -184,7 +194,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
&mut self,
|
||||
program: &ast::Program,
|
||||
symbol_table: SymbolTable,
|
||||
) -> Result<(), CompileError> {
|
||||
) -> CompileResult<()> {
|
||||
let size_before = self.output_stack.len();
|
||||
self.symbol_table_stack.push(symbol_table);
|
||||
|
||||
@@ -214,7 +224,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
&mut self,
|
||||
program: &ast::Program,
|
||||
symbol_table: SymbolTable,
|
||||
) -> Result<(), CompileError> {
|
||||
) -> CompileResult<()> {
|
||||
self.symbol_table_stack.push(symbol_table);
|
||||
|
||||
let mut emitted_return = false;
|
||||
@@ -253,25 +263,20 @@ impl<O: OutputStream> Compiler<O> {
|
||||
&mut self,
|
||||
statements: &[ast::Statement],
|
||||
symbol_table: SymbolTable,
|
||||
) -> Result<(), CompileError> {
|
||||
) -> CompileResult<()> {
|
||||
self.symbol_table_stack.push(symbol_table);
|
||||
for statement in statements {
|
||||
if let ast::StatementType::Expression { ref expression } = statement.node {
|
||||
self.compile_expression(expression)?;
|
||||
} else {
|
||||
return Err(CompileError {
|
||||
statement: None,
|
||||
error: CompileErrorType::ExpectExpr,
|
||||
location: statement.location.clone(),
|
||||
source_path: None,
|
||||
});
|
||||
return Err(self.error_loc(CompileErrorType::ExpectExpr, statement.location));
|
||||
}
|
||||
}
|
||||
self.emit(Instruction::ReturnValue);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compile_statements(&mut self, statements: &[ast::Statement]) -> Result<(), CompileError> {
|
||||
fn compile_statements(&mut self, statements: &[ast::Statement]) -> CompileResult<()> {
|
||||
for statement in statements {
|
||||
self.compile_statement(statement)?
|
||||
}
|
||||
@@ -304,9 +309,9 @@ impl<O: OutputStream> Compiler<O> {
|
||||
});
|
||||
}
|
||||
|
||||
fn compile_statement(&mut self, statement: &ast::Statement) -> Result<(), CompileError> {
|
||||
fn compile_statement(&mut self, statement: &ast::Statement) -> CompileResult<()> {
|
||||
trace!("Compiling {:?}", statement);
|
||||
self.set_source_location(&statement.location);
|
||||
self.set_source_location(statement.location);
|
||||
use ast::StatementType::*;
|
||||
|
||||
match &statement.node {
|
||||
@@ -443,7 +448,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
}
|
||||
Ok(end_label)
|
||||
})
|
||||
.collect::<Result<Vec<_>, CompileError>>()?;
|
||||
.collect::<CompileResult<Vec<_>>>()?;
|
||||
|
||||
self.compile_statements(body)?;
|
||||
|
||||
@@ -539,34 +544,21 @@ impl<O: OutputStream> Compiler<O> {
|
||||
}
|
||||
Break => {
|
||||
if !self.ctx.in_loop {
|
||||
return Err(CompileError {
|
||||
statement: None,
|
||||
error: CompileErrorType::InvalidBreak,
|
||||
location: statement.location.clone(),
|
||||
source_path: None,
|
||||
});
|
||||
return Err(self.error_loc(CompileErrorType::InvalidBreak, statement.location));
|
||||
}
|
||||
self.emit(Instruction::Break);
|
||||
}
|
||||
Continue => {
|
||||
if !self.ctx.in_loop {
|
||||
return Err(CompileError {
|
||||
statement: None,
|
||||
error: CompileErrorType::InvalidContinue,
|
||||
location: statement.location.clone(),
|
||||
source_path: None,
|
||||
});
|
||||
return Err(
|
||||
self.error_loc(CompileErrorType::InvalidContinue, statement.location)
|
||||
);
|
||||
}
|
||||
self.emit(Instruction::Continue);
|
||||
}
|
||||
Return { value } => {
|
||||
if !self.ctx.in_func() {
|
||||
return Err(CompileError {
|
||||
statement: None,
|
||||
error: CompileErrorType::InvalidReturn,
|
||||
location: statement.location.clone(),
|
||||
source_path: None,
|
||||
});
|
||||
return Err(self.error_loc(CompileErrorType::InvalidReturn, statement.location));
|
||||
}
|
||||
match value {
|
||||
Some(v) => {
|
||||
@@ -616,7 +608,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compile_delete(&mut self, expression: &ast::Expression) -> Result<(), CompileError> {
|
||||
fn compile_delete(&mut self, expression: &ast::Expression) -> CompileResult<()> {
|
||||
match &expression.node {
|
||||
ast::ExpressionType::Identifier { name } => {
|
||||
self.emit(Instruction::DeleteName {
|
||||
@@ -639,19 +631,12 @@ impl<O: OutputStream> Compiler<O> {
|
||||
self.compile_delete(element)?;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(CompileError {
|
||||
statement: None,
|
||||
error: CompileErrorType::Delete(expression.name()),
|
||||
location: self.current_source_location.clone(),
|
||||
source_path: None,
|
||||
});
|
||||
}
|
||||
_ => return Err(self.error(CompileErrorType::Delete(expression.name()))),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn enter_function(&mut self, name: &str, args: &ast::Parameters) -> Result<(), CompileError> {
|
||||
fn enter_function(&mut self, name: &str, args: &ast::Parameters) -> CompileResult<()> {
|
||||
let have_defaults = !args.defaults.is_empty();
|
||||
if have_defaults {
|
||||
// Construct a tuple:
|
||||
@@ -710,10 +695,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn prepare_decorators(
|
||||
&mut self,
|
||||
decorator_list: &[ast::Expression],
|
||||
) -> Result<(), CompileError> {
|
||||
fn prepare_decorators(&mut self, decorator_list: &[ast::Expression]) -> CompileResult<()> {
|
||||
for decorator in decorator_list {
|
||||
self.compile_expression(decorator)?;
|
||||
}
|
||||
@@ -735,7 +717,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
handlers: &[ast::ExceptHandler],
|
||||
orelse: &Option<ast::Suite>,
|
||||
finalbody: &Option<ast::Suite>,
|
||||
) -> Result<(), CompileError> {
|
||||
) -> CompileResult<()> {
|
||||
let mut handler_label = self.new_label();
|
||||
let finally_handler_label = self.new_label();
|
||||
let else_label = self.new_label();
|
||||
@@ -849,7 +831,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
decorator_list: &[ast::Expression],
|
||||
returns: &Option<ast::Expression>, // TODO: use type hint somehow..
|
||||
is_async: bool,
|
||||
) -> Result<(), CompileError> {
|
||||
) -> CompileResult<()> {
|
||||
// Create bytecode for this function:
|
||||
// remember to restore self.ctx.in_loop to the original after the function is compiled
|
||||
let prev_ctx = self.ctx;
|
||||
@@ -962,7 +944,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
bases: &[ast::Expression],
|
||||
keywords: &[ast::Keyword],
|
||||
decorator_list: &[ast::Expression],
|
||||
) -> Result<(), CompileError> {
|
||||
) -> CompileResult<()> {
|
||||
let prev_ctx = self.ctx;
|
||||
self.ctx = CompileContext {
|
||||
func: FunctionContext::NoFunction,
|
||||
@@ -1102,7 +1084,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
test: &ast::Expression,
|
||||
body: &[ast::Statement],
|
||||
orelse: &Option<Vec<ast::Statement>>,
|
||||
) -> Result<(), CompileError> {
|
||||
) -> CompileResult<()> {
|
||||
let start_label = self.new_label();
|
||||
let else_label = self.new_label();
|
||||
let end_label = self.new_label();
|
||||
@@ -1138,7 +1120,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
body: &[ast::Statement],
|
||||
orelse: &Option<Vec<ast::Statement>>,
|
||||
is_async: bool,
|
||||
) -> Result<(), CompileError> {
|
||||
) -> CompileResult<()> {
|
||||
// Start loop
|
||||
let start_label = self.new_label();
|
||||
let else_label = self.new_label();
|
||||
@@ -1223,7 +1205,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
&mut self,
|
||||
vals: &[ast::Expression],
|
||||
ops: &[ast::Comparison],
|
||||
) -> Result<(), CompileError> {
|
||||
) -> CompileResult<()> {
|
||||
assert!(!ops.is_empty());
|
||||
assert_eq!(vals.len(), ops.len() + 1);
|
||||
|
||||
@@ -1294,7 +1276,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
target: &ast::Expression,
|
||||
annotation: &ast::Expression,
|
||||
value: &Option<ast::Expression>,
|
||||
) -> Result<(), CompileError> {
|
||||
) -> CompileResult<()> {
|
||||
if let Some(value) = value {
|
||||
self.compile_expression(value)?;
|
||||
self.compile_store(target)?;
|
||||
@@ -1322,7 +1304,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compile_store(&mut self, target: &ast::Expression) -> Result<(), CompileError> {
|
||||
fn compile_store(&mut self, target: &ast::Expression) -> CompileResult<()> {
|
||||
match &target.node {
|
||||
ast::ExpressionType::Identifier { name } => {
|
||||
self.store_name(name);
|
||||
@@ -1345,12 +1327,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
for (i, element) in elements.iter().enumerate() {
|
||||
if let ast::ExpressionType::Starred { .. } = &element.node {
|
||||
if seen_star {
|
||||
return Err(CompileError {
|
||||
statement: None,
|
||||
error: CompileErrorType::StarArgs,
|
||||
location: self.current_source_location.clone(),
|
||||
source_path: None,
|
||||
});
|
||||
return Err(self.error(CompileErrorType::StarArgs));
|
||||
} else {
|
||||
seen_star = true;
|
||||
self.emit(Instruction::UnpackEx {
|
||||
@@ -1375,14 +1352,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(CompileError {
|
||||
statement: None,
|
||||
error: CompileErrorType::Assign(target.name()),
|
||||
location: self.current_source_location.clone(),
|
||||
source_path: None,
|
||||
});
|
||||
}
|
||||
_ => return Err(self.error(CompileErrorType::Assign(target.name()))),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -1420,7 +1390,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
expression: &ast::Expression,
|
||||
condition: bool,
|
||||
target_label: Label,
|
||||
) -> Result<(), CompileError> {
|
||||
) -> CompileResult<()> {
|
||||
// Compile expression for test, and jump to label if false
|
||||
match &expression.node {
|
||||
ast::ExpressionType::BoolOp { op, values } => {
|
||||
@@ -1498,7 +1468,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
&mut self,
|
||||
op: &ast::BooleanOperator,
|
||||
values: &[ast::Expression],
|
||||
) -> Result<(), CompileError> {
|
||||
) -> CompileResult<()> {
|
||||
let end_label = self.new_label();
|
||||
|
||||
let (last_value, values) = values.split_last().unwrap();
|
||||
@@ -1524,7 +1494,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
fn compile_dict(
|
||||
&mut self,
|
||||
pairs: &[(Option<ast::Expression>, ast::Expression)],
|
||||
) -> Result<(), CompileError> {
|
||||
) -> CompileResult<()> {
|
||||
let mut size = 0;
|
||||
let mut has_unpacking = false;
|
||||
for (is_unpacking, subpairs) in &pairs.iter().group_by(|e| e.0.is_none()) {
|
||||
@@ -1568,9 +1538,9 @@ impl<O: OutputStream> Compiler<O> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compile_expression(&mut self, expression: &ast::Expression) -> Result<(), CompileError> {
|
||||
fn compile_expression(&mut self, expression: &ast::Expression) -> CompileResult<()> {
|
||||
trace!("Compiling {:?}", expression);
|
||||
self.set_source_location(&expression.location);
|
||||
self.set_source_location(expression.location);
|
||||
|
||||
use ast::ExpressionType::*;
|
||||
match &expression.node {
|
||||
@@ -1662,12 +1632,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
}
|
||||
Yield { value } => {
|
||||
if !self.ctx.in_func() {
|
||||
return Err(CompileError {
|
||||
statement: Option::None,
|
||||
error: CompileErrorType::InvalidYield,
|
||||
location: self.current_source_location.clone(),
|
||||
source_path: Option::None,
|
||||
});
|
||||
return Err(self.error(CompileErrorType::InvalidYield));
|
||||
}
|
||||
self.mark_generator();
|
||||
match value {
|
||||
@@ -1758,14 +1723,11 @@ impl<O: OutputStream> Compiler<O> {
|
||||
self.compile_comprehension(kind, generators)?;
|
||||
}
|
||||
Starred { .. } => {
|
||||
return Err(CompileError {
|
||||
statement: Option::None,
|
||||
error: CompileErrorType::SyntaxError(std::string::String::from(
|
||||
return Err(
|
||||
self.error(CompileErrorType::SyntaxError(std::string::String::from(
|
||||
"Invalid starred expression",
|
||||
)),
|
||||
location: self.current_source_location.clone(),
|
||||
source_path: Option::None,
|
||||
});
|
||||
))),
|
||||
);
|
||||
}
|
||||
IfExpression { test, body, orelse } => {
|
||||
let no_label = self.new_label();
|
||||
@@ -1784,7 +1746,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compile_keywords(&mut self, keywords: &[ast::Keyword]) -> Result<(), CompileError> {
|
||||
fn compile_keywords(&mut self, keywords: &[ast::Keyword]) -> CompileResult<()> {
|
||||
let mut size = 0;
|
||||
for (is_unpacking, subkeywords) in &keywords.iter().group_by(|e| e.name.is_none()) {
|
||||
if is_unpacking {
|
||||
@@ -1828,7 +1790,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
function: &ast::Expression,
|
||||
args: &[ast::Expression],
|
||||
keywords: &[ast::Keyword],
|
||||
) -> Result<(), CompileError> {
|
||||
) -> CompileResult<()> {
|
||||
self.compile_expression(function)?;
|
||||
let count = args.len() + keywords.len();
|
||||
|
||||
@@ -1889,7 +1851,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
|
||||
// Given a vector of expr / star expr generate code which gives either
|
||||
// a list of expressions on the stack, or a list of tuples.
|
||||
fn gather_elements(&mut self, elements: &[ast::Expression]) -> Result<bool, CompileError> {
|
||||
fn gather_elements(&mut self, elements: &[ast::Expression]) -> CompileResult<bool> {
|
||||
// First determine if we have starred elements:
|
||||
let has_stars = elements.iter().any(|e| {
|
||||
if let ast::ExpressionType::Starred { .. } = &e.node {
|
||||
@@ -1920,7 +1882,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
&mut self,
|
||||
kind: &ast::ComprehensionKind,
|
||||
generators: &[ast::Comprehension],
|
||||
) -> Result<(), CompileError> {
|
||||
) -> CompileResult<()> {
|
||||
// We must have at least one generator:
|
||||
assert!(!generators.is_empty());
|
||||
|
||||
@@ -2087,7 +2049,7 @@ impl<O: OutputStream> Compiler<O> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compile_string(&mut self, string: &ast::StringGroup) -> Result<(), CompileError> {
|
||||
fn compile_string(&mut self, string: &ast::StringGroup) -> CompileResult<()> {
|
||||
if let Some(value) = try_get_constant_string(string) {
|
||||
self.emit(Instruction::LoadConst {
|
||||
value: bytecode::Constant::String { value },
|
||||
@@ -2182,8 +2144,8 @@ impl<O: OutputStream> Compiler<O> {
|
||||
self.current_output().set_label(label)
|
||||
}
|
||||
|
||||
fn set_source_location(&mut self, location: &ast::Location) {
|
||||
self.current_source_location = location.clone();
|
||||
fn set_source_location(&mut self, location: ast::Location) {
|
||||
self.current_source_location = location;
|
||||
}
|
||||
|
||||
fn get_source_line_number(&mut self) -> usize {
|
||||
|
||||
@@ -15,7 +15,7 @@ impl From<Vec<InstructionMetadata>> for InstructionMetadata {
|
||||
fn from(metas: Vec<Self>) -> Self {
|
||||
debug_assert!(!metas.is_empty(), "`metas` must not be empty");
|
||||
InstructionMetadata {
|
||||
loc: metas[0].loc.clone(),
|
||||
loc: metas[0].loc,
|
||||
labels: metas
|
||||
.into_iter()
|
||||
.flat_map(|meta| meta.labels.into_iter())
|
||||
|
||||
+1
-1
@@ -193,7 +193,7 @@ impl fmt::Display for ParseErrorType {
|
||||
ParseErrorType::UnrecognizedToken(ref tok, ref expected) => {
|
||||
if *tok == Tok::Indent {
|
||||
write!(f, "unexpected indent")
|
||||
} else if expected.clone() == Some("Indent".to_owned()) {
|
||||
} else if expected.as_deref() == Some("Indent") {
|
||||
write!(f, "expected an indented block")
|
||||
} else {
|
||||
write!(f, "Got unexpected token {}", tok)
|
||||
|
||||
@@ -22,7 +22,7 @@ pub fn parse_params(
|
||||
// have defaults
|
||||
return Err(LexicalError {
|
||||
error: LexicalErrorType::DefaultArgumentError,
|
||||
location: name.location.clone(),
|
||||
location: name.location,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+9
-11
@@ -285,7 +285,7 @@ where
|
||||
let end_pos = self.get_pos();
|
||||
let value = BigInt::from_str_radix(&value_text, radix).map_err(|e| LexicalError {
|
||||
error: LexicalErrorType::OtherError(format!("{:?}", e)),
|
||||
location: start_pos.clone(),
|
||||
location: start_pos,
|
||||
})?;
|
||||
Ok((start_pos, Tok::Int { value }, end_pos))
|
||||
}
|
||||
@@ -711,9 +711,8 @@ where
|
||||
Ordering::Greater => {
|
||||
// New indentation level:
|
||||
self.indentation_stack.push(indentation_level);
|
||||
let tok_start = self.get_pos();
|
||||
let tok_end = tok_start.clone();
|
||||
self.emit((tok_start, Tok::Indent, tok_end));
|
||||
let tok_pos = self.get_pos();
|
||||
self.emit((tok_pos, Tok::Indent, tok_pos));
|
||||
}
|
||||
Ordering::Less => {
|
||||
// One or more dedentations
|
||||
@@ -726,9 +725,8 @@ where
|
||||
match ordering {
|
||||
Ordering::Less => {
|
||||
self.indentation_stack.pop();
|
||||
let tok_start = self.get_pos();
|
||||
let tok_end = tok_start.clone();
|
||||
self.emit((tok_start, Tok::Dedent, tok_end));
|
||||
let tok_pos = self.get_pos();
|
||||
self.emit((tok_pos, Tok::Dedent, tok_pos));
|
||||
}
|
||||
Ordering::Equal => {
|
||||
// We arrived at proper level of indentation.
|
||||
@@ -786,16 +784,16 @@ where
|
||||
// Next, insert a trailing newline, if required.
|
||||
if !self.at_begin_of_line {
|
||||
self.at_begin_of_line = true;
|
||||
self.emit((tok_pos.clone(), Tok::Newline, tok_pos.clone()));
|
||||
self.emit((tok_pos, Tok::Newline, tok_pos));
|
||||
}
|
||||
|
||||
// Next, flush the indentation stack to zero.
|
||||
while self.indentation_stack.len() > 1 {
|
||||
self.indentation_stack.pop();
|
||||
self.emit((tok_pos.clone(), Tok::Dedent, tok_pos.clone()));
|
||||
self.emit((tok_pos, Tok::Dedent, tok_pos));
|
||||
}
|
||||
|
||||
self.emit((tok_pos.clone(), Tok::EndOfFile, tok_pos));
|
||||
self.emit((tok_pos, Tok::EndOfFile, tok_pos));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -1194,7 +1192,7 @@ where
|
||||
|
||||
/// Helper function to retrieve the current position.
|
||||
fn get_pos(&self) -> Location {
|
||||
self.location.clone()
|
||||
self.location
|
||||
}
|
||||
|
||||
/// Helper function to emit a lexed token to the queue of tokens.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use std::fmt;
|
||||
|
||||
/// A location somewhere in the sourcecode.
|
||||
#[derive(Clone, Debug, Default, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||
pub struct Location {
|
||||
row: usize,
|
||||
column: usize,
|
||||
|
||||
@@ -138,7 +138,7 @@ mod tests {
|
||||
|
||||
fn as_statement(expr: ast::Expression) -> ast::Statement {
|
||||
ast::Statement {
|
||||
location: expr.location.clone(),
|
||||
location: expr.location,
|
||||
node: ast::StatementType::Expression { expression: expr },
|
||||
}
|
||||
}
|
||||
|
||||
@@ -874,9 +874,9 @@ SubscriptList: ast::Expression = {
|
||||
Subscript: ast::Expression = {
|
||||
Test,
|
||||
<e1:Test?> <location:@L> ":" <e2:Test?> <e3:SliceOp?> => {
|
||||
let s1 = e1.unwrap_or(ast::Expression { location: location.clone(), node: ast::ExpressionType::None });
|
||||
let s2 = e2.unwrap_or(ast::Expression { location: location.clone(), node: ast::ExpressionType::None });
|
||||
let s3 = e3.unwrap_or(ast::Expression { location: location.clone(), node: ast::ExpressionType::None });
|
||||
let s1 = e1.unwrap_or(ast::Expression { location, node: ast::ExpressionType::None });
|
||||
let s2 = e2.unwrap_or(ast::Expression { location, node: ast::ExpressionType::None });
|
||||
let s3 = e3.unwrap_or(ast::Expression { location, node: ast::ExpressionType::None });
|
||||
ast::Expression {
|
||||
location,
|
||||
node: ast::ExpressionType::Slice { elements: vec![s1, s2, s3] }
|
||||
@@ -1061,7 +1061,7 @@ FunctionArgument: (Option<Option<String>>, ast::Expression) = {
|
||||
<e:Test> <c:CompFor?> => {
|
||||
let expr = match c {
|
||||
Some(c) => ast::Expression {
|
||||
location: e.location.clone(),
|
||||
location: e.location,
|
||||
node: ast::ExpressionType::Comprehension {
|
||||
kind: Box::new(ast::ComprehensionKind::GeneratorExpression { element: e }),
|
||||
generators: c,
|
||||
@@ -1071,7 +1071,7 @@ FunctionArgument: (Option<Option<String>>, ast::Expression) = {
|
||||
};
|
||||
(None, expr)
|
||||
},
|
||||
<i:Identifier> "=" <e:Test> => (Some(Some(i.clone())), e),
|
||||
<i:Identifier> "=" <e:Test> => (Some(Some(i)), e),
|
||||
<location:@L> "*" <e:Test> => (None, ast::Expression { location, node: ast::ExpressionType::Starred { value: Box::new(e) } }),
|
||||
"**" <e:Test> => (Some(None), e),
|
||||
};
|
||||
@@ -1105,7 +1105,7 @@ StringGroup: ast::StringGroup = {
|
||||
let mut values = vec![];
|
||||
for (value, is_fstring) in s {
|
||||
values.push(if is_fstring {
|
||||
parse_located_fstring(&value, loc.clone())?
|
||||
parse_located_fstring(&value, loc)?
|
||||
} else {
|
||||
ast::StringGroup::Constant { value }
|
||||
})
|
||||
|
||||
+1
-1
@@ -1348,7 +1348,7 @@ impl Frame {
|
||||
}
|
||||
|
||||
pub fn get_lineno(&self) -> bytecode::Location {
|
||||
self.code.locations[self.lasti.get()].clone()
|
||||
self.code.locations[self.lasti.get()]
|
||||
}
|
||||
|
||||
fn push_block(&self, typ: BlockType) {
|
||||
|
||||
Reference in new issue
Block a user