From bc23e60962da66d5a0dd15f9624d098d00d3975f Mon Sep 17 00:00:00 2001 From: Windel Bouwman Date: Sat, 20 Oct 2018 12:16:18 +0200 Subject: [PATCH] Add generator expression syntax --- parser/src/ast.rs | 1 + parser/src/python.lalrpop | 17 ++++++++++++++++- vm/src/compile.rs | 14 ++++++-------- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/parser/src/ast.rs b/parser/src/ast.rs index da49ad887..ae07058d9 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -210,6 +210,7 @@ pub struct Parameters { #[derive(Debug, PartialEq)] pub enum ComprehensionKind { + GeneratorExpression { element: Expression }, List { element: Expression }, Set { element: Expression }, Dict { key: Expression, value: Expression }, diff --git a/parser/src/python.lalrpop b/parser/src/python.lalrpop index f1bb14624..b2c1efdbd 100644 --- a/parser/src/python.lalrpop +++ b/parser/src/python.lalrpop @@ -707,6 +707,12 @@ Atom: ast::Expression = { } } }, + "(" ")" => { + ast::Expression::Comprehension { + kind: Box::new(ast::ComprehensionKind::GeneratorExpression { element: e }), + generators: c, + } + }, "{" "}" => ast::Expression::Dict { elements: e.unwrap_or(Vec::new()) }, "{" "}" => e, "{" "}" => ast::Expression::Set { elements: e }, @@ -862,7 +868,16 @@ ArgumentList: (Vec, Vec) = { }; FunctionArgument: (Option, ast::Expression) = { - => (None, e), + => { + let expr = match c { + Some(c) => ast::Expression::Comprehension { + kind: Box::new(ast::ComprehensionKind::GeneratorExpression { element: e }), + generators: c, + }, + None => e, + }; + (None, expr) + }, "=" => (Some(i.clone()), e), }; diff --git a/vm/src/compile.rs b/vm/src/compile.rs index b8d5b53de..0d356df3e 100644 --- a/vm/src/compile.rs +++ b/vm/src/compile.rs @@ -933,6 +933,7 @@ impl Compiler { assert!(generators.len() > 0); let name = match kind { + ast::ComprehensionKind::GeneratorExpression { .. } => "", ast::ComprehensionKind::List { .. } => "", ast::ComprehensionKind::Set { .. } => "", ast::ComprehensionKind::Dict { .. } => "", @@ -948,6 +949,7 @@ impl Compiler { // Create empty object of proper type: match kind { + ast::ComprehensionKind::GeneratorExpression { .. } => {} ast::ComprehensionKind::List { .. } => { self.emit(Instruction::BuildList { size: 0 }); } @@ -990,30 +992,26 @@ impl Compiler { } match kind { + ast::ComprehensionKind::GeneratorExpression { element } => { + self.compile_expression(element)?; + self.emit(Instruction::YieldValue); + } ast::ComprehensionKind::List { element } => { - // Evaluate element: self.compile_expression(element)?; - - // List append: self.emit(Instruction::ListAppend { i: 1 + generators.len(), }); } ast::ComprehensionKind::Set { element } => { - // Evaluate element: self.compile_expression(element)?; - - // List append: self.emit(Instruction::SetAdd { i: 1 + generators.len(), }); } ast::ComprehensionKind::Dict { key, value } => { - // Evaluate value and element: self.compile_expression(value)?; self.compile_expression(key)?; - // List append: self.emit(Instruction::MapAdd { i: 1 + generators.len(), });