Skip to content

Commit bc23e60

Browse files
committed
Add generator expression syntax
1 parent c54e443 commit bc23e60

File tree

3 files changed

+23
-9
lines changed

3 files changed

+23
-9
lines changed

parser/src/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ pub struct Parameters {
210210

211211
#[derive(Debug, PartialEq)]
212212
pub enum ComprehensionKind {
213+
GeneratorExpression { element: Expression },
213214
List { element: Expression },
214215
Set { element: Expression },
215216
Dict { key: Expression, value: Expression },

parser/src/python.lalrpop

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,12 @@ Atom: ast::Expression = {
707707
}
708708
}
709709
},
710+
"(" <e:Test> <c:CompFor> ")" => {
711+
ast::Expression::Comprehension {
712+
kind: Box::new(ast::ComprehensionKind::GeneratorExpression { element: e }),
713+
generators: c,
714+
}
715+
},
710716
"{" <e:TestDict?> "}" => ast::Expression::Dict { elements: e.unwrap_or(Vec::new()) },
711717
"{" <e:TestDictComp> "}" => e,
712718
"{" <e:TestSet> "}" => ast::Expression::Set { elements: e },
@@ -862,7 +868,16 @@ ArgumentList: (Vec<ast::Expression>, Vec<ast::Keyword>) = {
862868
};
863869

864870
FunctionArgument: (Option<String>, ast::Expression) = {
865-
<e:Test> => (None, e),
871+
<e:Test> <c:CompFor?> => {
872+
let expr = match c {
873+
Some(c) => ast::Expression::Comprehension {
874+
kind: Box::new(ast::ComprehensionKind::GeneratorExpression { element: e }),
875+
generators: c,
876+
},
877+
None => e,
878+
};
879+
(None, expr)
880+
},
866881
<i:Identifier> "=" <e:Test> => (Some(i.clone()), e),
867882
};
868883

vm/src/compile.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,7 @@ impl Compiler {
933933
assert!(generators.len() > 0);
934934

935935
let name = match kind {
936+
ast::ComprehensionKind::GeneratorExpression { .. } => "<genexpr>",
936937
ast::ComprehensionKind::List { .. } => "<listcomp>",
937938
ast::ComprehensionKind::Set { .. } => "<setcomp>",
938939
ast::ComprehensionKind::Dict { .. } => "<dictcomp>",
@@ -948,6 +949,7 @@ impl Compiler {
948949

949950
// Create empty object of proper type:
950951
match kind {
952+
ast::ComprehensionKind::GeneratorExpression { .. } => {}
951953
ast::ComprehensionKind::List { .. } => {
952954
self.emit(Instruction::BuildList { size: 0 });
953955
}
@@ -990,30 +992,26 @@ impl Compiler {
990992
}
991993

992994
match kind {
995+
ast::ComprehensionKind::GeneratorExpression { element } => {
996+
self.compile_expression(element)?;
997+
self.emit(Instruction::YieldValue);
998+
}
993999
ast::ComprehensionKind::List { element } => {
994-
// Evaluate element:
9951000
self.compile_expression(element)?;
996-
997-
// List append:
9981001
self.emit(Instruction::ListAppend {
9991002
i: 1 + generators.len(),
10001003
});
10011004
}
10021005
ast::ComprehensionKind::Set { element } => {
1003-
// Evaluate element:
10041006
self.compile_expression(element)?;
1005-
1006-
// List append:
10071007
self.emit(Instruction::SetAdd {
10081008
i: 1 + generators.len(),
10091009
});
10101010
}
10111011
ast::ComprehensionKind::Dict { key, value } => {
1012-
// Evaluate value and element:
10131012
self.compile_expression(value)?;
10141013
self.compile_expression(key)?;
10151014

1016-
// List append:
10171015
self.emit(Instruction::MapAdd {
10181016
i: 1 + generators.len(),
10191017
});

0 commit comments

Comments
 (0)