Skip to content

Commit b5696c8

Browse files
committed
Port Python 2.7 list comprehension fixes by @reductor from #78
1 parent 314f4a1 commit b5696c8

File tree

4 files changed

+40
-2
lines changed

4 files changed

+40
-2
lines changed

ASTNode.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,14 +497,17 @@ class ASTIterBlock : public ASTBlock {
497497

498498
PycRef<ASTNode> iter() const { return m_iter; }
499499
PycRef<ASTNode> index() const { return m_idx; }
500+
PycRef<ASTNode> condition() const { return m_cond; }
500501
bool isComprehension() const { return m_comp; }
501502

502503
void setIndex(PycRef<ASTNode> idx) { m_idx = idx; init(); }
504+
void setCondition(PycRef<ASTNode> cond) { m_cond = cond; }
503505
void setComprehension(bool comp) { m_comp = comp; }
504506

505507
private:
506508
PycRef<ASTNode> m_iter;
507509
PycRef<ASTNode> m_idx;
510+
PycRef<ASTNode> m_cond;
508511
bool m_comp;
509512
};
510513

ASTree.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
272272
}
273273
break;
274274
case Pyc::BUILD_MAP_A:
275-
if (mod->majorVer() > 3 || (mod->majorVer() == 3 && mod->minorVer() >= 5)) {
275+
if (mod->verCompare(3, 5) >= 0) {
276276
auto map = new ASTMap;
277277
for (int i=0; i<operand; ++i) {
278278
PycRef<ASTNode> value = stack.top();
@@ -1029,6 +1029,15 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
10291029
newcond = new ASTBinary(cond1, cond, ASTBinary::BIN_LOG_OR);
10301030
}
10311031
ifblk = new ASTCondBlock(top->blktype(), offs, newcond, neg);
1032+
} else if (curblock->blktype() == ASTBlock::BLK_FOR
1033+
&& curblock.cast<ASTIterBlock>()->isComprehension()
1034+
&& mod->verCompare(2, 7) >= 0) {
1035+
/* Comprehension condition */
1036+
curblock.cast<ASTIterBlock>()->setCondition(cond);
1037+
stack_hist.pop();
1038+
// TODO: Handle older python versions, where condition
1039+
// is laid out a little differently.
1040+
break;
10321041
} else {
10331042
/* Plain old if statement */
10341043
ifblk = new ASTCondBlock(ASTBlock::BLK_IF, offs, cond, neg);
@@ -1056,7 +1065,7 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
10561065

10571066
blocks.pop();
10581067
curblock = blocks.top();
1059-
} if (curblock->blktype() == ASTBlock::BLK_ELSE) {
1068+
} else if (curblock->blktype() == ASTBlock::BLK_ELSE) {
10601069
stack = stack_hist.top();
10611070
stack_hist.pop();
10621071

@@ -1271,6 +1280,7 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
12711280

12721281
if (curblock->blktype() == ASTBlock::BLK_FOR
12731282
&& curblock.cast<ASTIterBlock>()->isComprehension()) {
1283+
stack.pop();
12741284
stack.push(new ASTComprehension(value));
12751285
} else {
12761286
stack.push(new ASTSubscr(list, value)); /* Total hack */
@@ -2333,6 +2343,10 @@ void print_src(PycRef<ASTNode> node, PycModule* mod)
23332343
print_src(gen->index(), mod);
23342344
fputs(" in ", pyc_output);
23352345
print_src(gen->iter(), mod);
2346+
if (gen->condition()) {
2347+
fprintf(pyc_output, " if ");
2348+
print_src(gen->condition(), mod);
2349+
}
23362350
}
23372351
fputs(" ]", pyc_output);
23382352
}
982 Bytes
Binary file not shown.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
XXX = range ( 4 ) <EOL>
2+
print [ i for i in XXX ] <EOL>
3+
print <EOL>
4+
print [ i for i in ( 1 , 2 , 3 , 4 ) ] <EOL>
5+
print <EOL>
6+
print [ ( i , 1 ) for i in XXX ] <EOL>
7+
print <EOL>
8+
print [ i * 2 for i in range ( 4 ) ] <EOL>
9+
print <EOL>
10+
print [ i * j for i in range ( 4 ) for j in range ( 7 ) ] <EOL>
11+
print [ i * 2 for i in range ( 4 ) if i == 0 ] <EOL>
12+
print [ ( i , i ** 2 ) for i in range ( 4 ) if i % 2 == 0 ] <EOL>
13+
print [ i * j for i in range ( 4 ) if i == 2 for j in range ( 7 ) if i + i % 2 == 0 ] <EOL>
14+
seq1 = 'abc' <EOL>
15+
seq2 = ( 1 , 2 , 3 ) <EOL>
16+
[ ( x , y ) for x in seq1 for y in seq2 ] <EOL>
17+
def flatten ( seq ) : <EOL>
18+
<INDENT>
19+
return [ x for subseq in seq for x in subseq ] <EOL>
20+
<OUTDENT>
21+
print flatten ( [ [ 0 ] , [ 1 , 2 , 3 ] , [ 4 , 5 ] , [ 6 , 7 , 8 , 9 ] , [ ] ] ) <EOL>

0 commit comments

Comments
 (0)