Skip to content

Commit 1fddce4

Browse files
committed
Implement review comments and improve parsing a bit.
1 parent a06bd3e commit 1fddce4

File tree

8 files changed

+129
-119
lines changed

8 files changed

+129
-119
lines changed

compiler/src/compile.rs

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -385,35 +385,47 @@ impl Compiler {
385385
}
386386
self.set_label(end_label);
387387
}
388-
With { items, body } => {
389-
let end_label = self.new_label();
390-
for item in items {
391-
self.compile_expression(&item.context_expr)?;
392-
self.emit(Instruction::SetupWith { end: end_label });
393-
match &item.optional_vars {
394-
Some(var) => {
395-
self.compile_store(var)?;
396-
}
397-
None => {
398-
self.emit(Instruction::Pop);
388+
With {
389+
is_async,
390+
items,
391+
body,
392+
} => {
393+
if *is_async {
394+
unimplemented!("async with");
395+
} else {
396+
let end_label = self.new_label();
397+
for item in items {
398+
self.compile_expression(&item.context_expr)?;
399+
self.emit(Instruction::SetupWith { end: end_label });
400+
match &item.optional_vars {
401+
Some(var) => {
402+
self.compile_store(var)?;
403+
}
404+
None => {
405+
self.emit(Instruction::Pop);
406+
}
399407
}
400408
}
401-
}
402409

403-
self.compile_statements(body)?;
404-
for _ in 0..items.len() {
405-
self.emit(Instruction::CleanupWith { end: end_label });
410+
self.compile_statements(body)?;
411+
for _ in 0..items.len() {
412+
self.emit(Instruction::CleanupWith { end: end_label });
413+
}
414+
self.set_label(end_label);
406415
}
407-
self.set_label(end_label);
408416
}
409417
For {
418+
is_async,
410419
target,
411420
iter,
412421
body,
413422
orelse,
414-
} => self.compile_for(target, iter, body, orelse)?,
415-
AsyncFor { .. } => {
416-
unimplemented!("async for");
423+
} => {
424+
if *is_async {
425+
unimplemented!("async for");
426+
} else {
427+
self.compile_for(target, iter, body, orelse)?
428+
}
417429
}
418430
Raise { exception, cause } => match exception {
419431
Some(value) => {
@@ -439,14 +451,18 @@ impl Compiler {
439451
finalbody,
440452
} => self.compile_try_statement(body, handlers, orelse, finalbody)?,
441453
FunctionDef {
454+
is_async,
442455
name,
443456
args,
444457
body,
445458
decorator_list,
446459
returns,
447-
} => self.compile_function_def(name, args, body, decorator_list, returns)?,
448-
AsyncFunctionDef { .. } => {
449-
unimplemented!("async def");
460+
} => {
461+
if *is_async {
462+
unimplemented!("async def");
463+
} else {
464+
self.compile_function_def(name, args, body, decorator_list, returns)?
465+
}
450466
}
451467
ClassDef {
452468
name,

compiler/src/symboltable.rs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -240,13 +240,7 @@ impl SymbolTableBuilder {
240240
args,
241241
decorator_list,
242242
returns,
243-
}
244-
| AsyncFunctionDef {
245-
name,
246-
body,
247-
args,
248-
decorator_list,
249-
returns,
243+
..
250244
} => {
251245
self.scan_expressions(decorator_list)?;
252246
self.register_name(name, SymbolRole::Assigned)?;
@@ -289,12 +283,7 @@ impl SymbolTableBuilder {
289283
iter,
290284
body,
291285
orelse,
292-
}
293-
| AsyncFor {
294-
target,
295-
iter,
296-
body,
297-
orelse,
286+
..
298287
} => {
299288
self.scan_expression(target)?;
300289
self.scan_expression(iter)?;
@@ -346,7 +335,7 @@ impl SymbolTableBuilder {
346335
self.scan_expression(target)?;
347336
self.scan_expression(value)?;
348337
}
349-
With { items, body } => {
338+
With { items, body, .. } => {
350339
for item in items {
351340
self.scan_expression(&item.context_expr)?;
352341
if let Some(expression) = &item.optional_vars {

examples/parse_folder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::path::Path;
1818

1919
fn main() {
2020
env_logger::init();
21-
let app = App::new("RustPython")
21+
let app = App::new("parse_folders")
2222
.version(crate_version!())
2323
.author(crate_authors!())
2424
.about("Walks over all .py files in a folder, and parses them.")
@@ -53,7 +53,7 @@ fn parse_folder(path: &Path) -> std::io::Result<Vec<ast::Program>> {
5353
res.extend(x);
5454
}
5555

56-
if metadata.is_file() && path.extension().map(|s| s.to_str().unwrap()) == Some("py") {
56+
if metadata.is_file() && path.extension().and_then(|s| s.to_str()) == Some("py") {
5757
match parse_python_file(&path) {
5858
Ok(x) => res.push(x),
5959
Err(y) => error!("Erreur in file {:?} {:?}", path, y),

parser/src/ast.rs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,12 @@ pub enum StatementType {
9494
orelse: Option<Vec<Statement>>,
9595
},
9696
With {
97+
is_async: bool,
9798
items: Vec<WithItem>,
9899
body: Vec<Statement>,
99100
},
100101
For {
101-
target: Expression,
102-
iter: Expression,
103-
body: Vec<Statement>,
104-
orelse: Option<Vec<Statement>>,
105-
},
106-
AsyncFor {
102+
is_async: bool,
107103
target: Expression,
108104
iter: Expression,
109105
body: Vec<Statement>,
@@ -127,13 +123,7 @@ pub enum StatementType {
127123
decorator_list: Vec<Expression>,
128124
},
129125
FunctionDef {
130-
name: String,
131-
args: Parameters,
132-
body: Vec<Statement>,
133-
decorator_list: Vec<Expression>,
134-
returns: Option<Expression>,
135-
},
136-
AsyncFunctionDef {
126+
is_async: bool,
137127
name: String,
138128
args: Parameters,
139129
body: Vec<Statement>,

parser/src/lexer.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,13 @@ where
694694
spaces = 0;
695695
tabs = 0;
696696
}
697+
Some('\x0C') => {
698+
// Form feed character!
699+
// Reset indentation for the Emacs user.
700+
self.next_char();
701+
spaces = 0;
702+
tabs = 0;
703+
}
697704
Some('\n') => {
698705
// Empty line!
699706
self.next_char();
@@ -1157,10 +1164,11 @@ where
11571164
self.emit((tok_start, Tok::Newline, tok_end));
11581165
}
11591166
}
1160-
' ' | '\t' => {
1167+
' ' | '\t' | '\x0C' => {
11611168
// Skip whitespaces
11621169
self.next_char();
1163-
while self.chr0 == Some(' ') || self.chr0 == Some('\t') {
1170+
while self.chr0 == Some(' ') || self.chr0 == Some('\t') || self.chr0 == Some('\x0C')
1171+
{
11641172
self.next_char();
11651173
}
11661174
}

parser/src/parser.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ mod tests {
306306
ast::Statement {
307307
location: ast::Location::new(2, 2),
308308
node: ast::StatementType::FunctionDef {
309+
is_async: false,
309310
name: String::from("__init__"),
310311
args: ast::Parameters {
311312
args: vec![ast::Parameter {
@@ -329,6 +330,7 @@ mod tests {
329330
ast::Statement {
330331
location: ast::Location::new(4, 2),
331332
node: ast::StatementType::FunctionDef {
333+
is_async: false,
332334
name: String::from("method_with_default"),
333335
args: ast::Parameters {
334336
args: vec![

parser/src/python.lalrpop

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -334,14 +334,11 @@ WhileStatement: ast::Statement = {
334334

335335
ForStatement: ast::Statement = {
336336
<location:@L> <is_async:"async"?> "for" <target:ExpressionList> "in" <iter:TestList> ":" <body:Suite> <s2:("else" ":" Suite)?> => {
337+
let is_async = is_async.is_some();
337338
let orelse = s2.map(|s| s.2);
338339
ast::Statement {
339340
location,
340-
node: if is_async.is_some() {
341-
ast::StatementType::AsyncFor { target, iter, body, orelse }
342-
} else {
343-
ast::StatementType::For { target, iter, body, orelse }
344-
},
341+
node: ast::StatementType::For { is_async, target, iter, body, orelse },
345342
}
346343
},
347344
};
@@ -380,10 +377,11 @@ ExceptClause: ast::ExceptHandler = {
380377
};
381378

382379
WithStatement: ast::Statement = {
383-
<location:@L> "with" <items:OneOrMore<WithItem>> ":" <s:Suite> => {
380+
<location:@L> <is_async:"async"?> "with" <items:OneOrMore<WithItem>> ":" <body:Suite> => {
381+
let is_async = is_async.is_some();
384382
ast::Statement {
385383
location,
386-
node: ast::StatementType::With { items: items, body: s },
384+
node: ast::StatementType::With { is_async, items, body },
387385
}
388386
},
389387
};
@@ -396,26 +394,18 @@ WithItem: ast::WithItem = {
396394
};
397395

398396
FuncDef: ast::Statement = {
399-
<d:Decorator*> <location:@L> <is_async:"async"?> "def" <i:Identifier> <a:Parameters> <r:("->" Test)?> ":" <s:Suite> => {
397+
<d:Decorator*> <location:@L> <is_async:"async"?> "def" <name:Identifier> <a:Parameters> <r:("->" Test)?> ":" <body:Suite> => {
398+
let is_async = is_async.is_some();
400399
ast::Statement {
401400
location,
402-
node: if is_async.is_some() {
403-
ast::StatementType::AsyncFunctionDef {
404-
name: i,
405-
args: a,
406-
body: s,
407-
decorator_list: d,
408-
returns: r.map(|x| x.1),
409-
}
410-
} else {
411-
ast::StatementType::FunctionDef {
412-
name: i,
413-
args: a,
414-
body: s,
415-
decorator_list: d,
416-
returns: r.map(|x| x.1),
417-
}
418-
}
401+
node: ast::StatementType::FunctionDef {
402+
is_async,
403+
name,
404+
args: a,
405+
body,
406+
decorator_list: d,
407+
returns: r.map(|x| x.1),
408+
}
419409
}
420410
},
421411
};

0 commit comments

Comments
 (0)