Skip to content

Commit 345544d

Browse files
committed
if/elif/else statements using ASTBlocks
1 parent 427e05b commit 345544d

File tree

4 files changed

+114
-69
lines changed

4 files changed

+114
-69
lines changed

ASTNode.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ void ASTBlock::removeFirst()
6767
const char* ASTBlock::type_str() const
6868
{
6969
static const char* s_type_strings[] = {
70-
"", "try", "except", "finally", "while", "for"
70+
"", "if", "else", "elif", "try", "except", "finally", "while", "for"
7171
};
72-
return s_type_strings[type()];
72+
return s_type_strings[blktype()];
7373
}

ASTNode.h

+24-11
Original file line numberDiff line numberDiff line change
@@ -336,31 +336,44 @@ class ASTBlock : public ASTNode {
336336
public:
337337
typedef std::list<PycRef<ASTNode> > list_t;
338338

339-
enum Type {
340-
BLK_MAIN, BLK_TRY, BLK_EXCEPT, BLK_FINALLY, BLK_WHILE, BLK_FOR
339+
enum BlkType {
340+
BLK_MAIN, BLK_IF, BLK_ELSE, BLK_ELIF, BLK_TRY, BLK_EXCEPT,
341+
BLK_FINALLY, BLK_WHILE, BLK_FOR
341342
};
342343

343-
ASTBlock(Type type, unsigned int start = 0, unsigned int end = 0)
344-
: ASTNode(NODE_BLOCK), m_type(type), m_start(start), m_end(end)
345-
{ }
344+
ASTBlock(BlkType blktype, unsigned int end = 0)
345+
: ASTNode(NODE_BLOCK), m_blktype(blktype), m_end(end) { }
346346

347-
Type type() const { return m_type; }
348-
unsigned int start() const { return m_start; }
347+
BlkType blktype() const { return m_blktype; }
349348
unsigned int end() const { return m_end; }
350349
const list_t& nodes() const { return m_nodes; }
350+
list_t::size_type size() const { return m_nodes.size(); }
351351
void removeFirst();
352352
void removeLast();
353353
void append(PycRef<ASTNode> node) { m_nodes.push_back(node); }
354354
const char* type_str() const;
355355

356356
private:
357-
Type m_type;
358-
unsigned int m_start;
357+
BlkType m_blktype;
359358
unsigned int m_end;
360359
list_t m_nodes;
361360
};
362361

363-
class ASTTryBlock : public ASTBlock {
362+
class ASTCondBlock : public ASTBlock {
363+
public:
364+
ASTCondBlock(ASTBlock::BlkType blktype, unsigned int end, PycRef<ASTNode> cond,
365+
bool negative = false)
366+
: ASTBlock(blktype, end), m_cond(cond), m_negative(negative) { }
367+
368+
PycRef<ASTNode> cond() const { return m_cond; }
369+
bool negative() const { return m_negative; }
370+
371+
private:
372+
PycRef<ASTNode> m_cond;
373+
bool m_negative;
374+
};
375+
376+
/*class ASTTryBlock : public ASTBlock {
364377
public:
365378
ASTTryBlock(unsigned int start, unsigned int end,
366379
unsigned int except = 0, unsigned int finally = 0)
@@ -376,6 +389,6 @@ class ASTTryBlock : public ASTBlock {
376389
private:
377390
unsigned int m_except;
378391
unsigned int m_finally;
379-
};
392+
};*/
380393

381394
#endif

ASTree.cpp

+76-50
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
240240
break;
241241
case Pyc::END_FINALLY:
242242
{
243-
if (curblock->type() == ASTBlock::BLK_FINALLY) {
243+
if (curblock->blktype() == ASTBlock::BLK_FINALLY) {
244244
blocks.pop();
245245
blocks.top()->append(curblock.cast<ASTNode>());
246246

@@ -291,40 +291,59 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
291291
break;
292292
case Pyc::JUMP_IF_FALSE_A:
293293
{
294+
stack_hist.push(stack);
295+
//stack = FastStack(stack_hist.top());
294296
PycRef<ASTNode> cond = stack.top();
295-
stack.pop();
296-
stack.push(new ASTJump(operand, ASTJump::JMP_FALSE, cond));
297-
jumps.push(pos + operand);
298-
startBlock = true;
297+
// Do not pop the condition off the stack!
298+
299+
PycRef<ASTBlock> ifblk;
300+
301+
if (curblock->blktype() == ASTBlock::BLK_ELSE && curblock->size() == 0) {
302+
blocks.pop();
303+
ifblk = new ASTCondBlock(ASTBlock::BLK_ELIF, pos+operand, cond, false);
304+
} else {
305+
ifblk = new ASTCondBlock(ASTBlock::BLK_IF, pos+operand, cond, false);
306+
}
307+
blocks.push(ifblk.cast<ASTBlock>());
308+
curblock = blocks.top();
299309
}
300310
break;
301311
case Pyc::JUMP_IF_TRUE_A:
302312
{
313+
stack_hist.push(stack);
314+
//stack = FastStack(stack_hist.top());
303315
PycRef<ASTNode> cond = stack.top();
304-
stack.pop();
305-
stack.push(new ASTJump(operand, ASTJump::JMP_TRUE, cond));
306-
jumps.push(pos + operand);
307-
startBlock = true;
316+
// Do not pop the condition off the stack!
317+
318+
PycRef<ASTBlock> ifblk;
319+
320+
if (curblock->blktype() == ASTBlock::BLK_ELSE && curblock->size() == 0) {
321+
blocks.pop();
322+
ifblk = new ASTCondBlock(ASTBlock::BLK_ELIF, pos+operand, cond, true);
323+
} else {
324+
ifblk = new ASTCondBlock(ASTBlock::BLK_IF, pos+operand, cond, true);
325+
}
326+
blocks.push(ifblk.cast<ASTBlock>());
327+
curblock = blocks.top();
308328
}
309329
break;
310330
case Pyc::JUMP_FORWARD_A:
311331
{
312-
stack.push(new ASTJump(operand, ASTJump::JUMP, NULL));
313-
/*std::stack<int> tmp;
314-
int top = jumps.top();
315-
while (top < pos + operand) {
316-
tmp.push(jumps.top());
317-
jumps.pop();
318-
if (!jumps.size())
319-
break;
320-
top = jumps.top();
321-
}
322-
jumps.push(pos + operand);
323-
while (tmp.size()) {
324-
jumps.push(tmp.top());
325-
tmp.pop();
332+
//stack = FastStack(stack_hist.top());
333+
stack_hist.pop();
334+
335+
PycRef<ASTBlock> prev = curblock;
336+
blocks.pop();
337+
338+
blocks.top()->append(prev.cast<ASTNode>());
339+
340+
if (operand > 1 && (prev->blktype() == ASTBlock::BLK_IF
341+
|| prev->blktype() == ASTBlock::BLK_ELIF))
342+
{
343+
PycRef<ASTBlock> next = new ASTBlock(ASTBlock::BLK_ELSE, pos+operand);
344+
blocks.push(next.cast<ASTBlock>());
326345
}
327-
startBlock = true;*/
346+
curblock = blocks.top();
328347
}
329348
break;
330349
case Pyc::LOAD_ATTR_A:
@@ -374,7 +393,7 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
374393
stack.push(new ASTFunction(code, defArgs));
375394
}
376395
break;
377-
case Pyc::POP_BLOCK:
396+
/*case Pyc::POP_BLOCK:
378397
{
379398
PycRef<ASTBlock> tmp = curblock;
380399
@@ -392,21 +411,15 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
392411
//todo
393412
}
394413
}
395-
break;
414+
break;*/
396415
case Pyc::POP_TOP:
397416
{
398417
PycRef<ASTNode> value = stack.top();
399418
stack.pop();
400-
if (value->type() == ASTNode::NODE_CALL || value->type() == ASTNode::NODE_JUMP) {
419+
if (value->type() == ASTNode::NODE_CALL) {
401420
lines.top().push_back(value);
402421
curblock->append(value);
403422
}
404-
405-
/*if (startBlock) {
406-
ASTNodeList::list_t blk;
407-
lines.push(blk);
408-
startBlock = false;
409-
}*/
410423
}
411424
break;
412425
case Pyc::PRINT_ITEM:
@@ -442,7 +455,7 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
442455
case Pyc::SET_LINENO_A:
443456
// Ignore
444457
break;
445-
case Pyc::SETUP_EXCEPT_A:
458+
/*case Pyc::SETUP_EXCEPT_A:
446459
{
447460
if (curblock->type() == ASTBlock::BLK_TRY) {
448461
PycRef<ASTTryBlock> tryblk = curblock.cast<ASTTryBlock>();
@@ -459,14 +472,14 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
459472
curblock = blocks.top();
460473
}
461474
}
462-
break;
463-
case Pyc::SETUP_FINALLY_A:
475+
break;*/
476+
/*case Pyc::SETUP_FINALLY_A:
464477
{
465478
PycRef<ASTBlock> tryblk = new ASTTryBlock(pos, pos+operand, 0, pos+operand);
466479
blocks.push(tryblk.cast<ASTBlock>());
467480
curblock = blocks.top();
468481
}
469-
break;
482+
break;*/
470483
case Pyc::STORE_ATTR_A:
471484
{
472485
PycRef<ASTNode> name = stack.top();
@@ -566,16 +579,15 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
566579
return new ASTNodeList(defblock->nodes());
567580
}
568581

569-
/*while (jumps.size() && jumps.top() == pos)
570-
{
571-
ASTNodeList::list_t block = lines.top();
572-
if (lines.size() > 1)
573-
{
574-
lines.pop();
575-
}
576-
lines.top().push_back(new ASTNodeList(block));
577-
jumps.pop();
578-
}*/
582+
if (curblock->end() && curblock->end() < pos) {
583+
//stack = FastStack(stack_hist.top());
584+
stack_hist.pop();
585+
586+
PycRef<ASTBlock> prev = curblock;
587+
blocks.pop();
588+
curblock = blocks.top();
589+
curblock->append(prev.cast<ASTNode>());
590+
}
579591
}
580592

581593
cleanBuild = true;
@@ -766,15 +778,29 @@ void print_src(PycRef<ASTNode> node, PycModule* mod)
766778
break;
767779
case ASTNode::NODE_BLOCK:
768780
{
769-
printf("%s:\n", node.cast<ASTBlock>()->type_str());
781+
printf("%s", node.cast<ASTBlock>()->type_str());
782+
if (node.cast<ASTBlock>()->blktype() == ASTBlock::BLK_IF
783+
|| node.cast<ASTBlock>()->blktype() == ASTBlock::BLK_ELIF)
784+
{
785+
if (node.cast<ASTCondBlock>()->negative())
786+
printf(" not ");
787+
else
788+
printf(" ");
789+
790+
print_src(node.cast<ASTCondBlock>()->cond(), mod);
791+
}
792+
printf(":\n");
793+
770794
cur_indent++;
771795
ASTBlock::list_t lines = node.cast<ASTBlock>()->nodes();
772-
for (ASTBlock::list_t::const_iterator ln = lines.begin(); ln != lines.end(); ++ln) {
796+
for (ASTBlock::list_t::const_iterator ln = lines.begin(); ln != lines.end();) {
773797
if ((*ln).cast<ASTNode>()->type() != ASTNode::NODE_NODELIST) {
774798
start_line(cur_indent);
775799
}
776800
print_src(*ln, mod);
777-
end_line();
801+
if (++ln != lines.end()) {
802+
end_line();
803+
}
778804
}
779805
cur_indent--;
780806
}

object.h

+12-6
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,27 @@ class PycRef {
66
public:
77
PycRef() : m_obj(0) { }
88
PycRef(_Obj* obj) : m_obj(obj) { m_obj->addRef(); }
9-
PycRef(const PycRef<_Obj>& obj) : m_obj(obj.m_obj) { m_obj->addRef(); }
10-
~PycRef<_Obj>() { m_obj->delRef(); }
9+
PycRef(const PycRef<_Obj>& obj) : m_obj(obj.m_obj) {
10+
if (m_obj != (_Obj*)0) m_obj->addRef();
11+
}
12+
~PycRef<_Obj>() { if (m_obj != (_Obj*)0) m_obj->delRef(); }
1113

1214
PycRef<_Obj>& operator=(_Obj* obj)
1315
{
14-
obj->addRef();
15-
m_obj->delRef();
16+
if (obj != (_Obj*)0)
17+
obj->addRef();
18+
if (m_obj != (_Obj*)0)
19+
m_obj->delRef();
1620
m_obj = obj;
1721
return *this;
1822
}
1923

2024
PycRef<_Obj>& operator=(const PycRef<_Obj>& obj)
2125
{
22-
obj.m_obj->addRef();
23-
m_obj->delRef();
26+
if (obj.m_obj != (_Obj*)0)
27+
obj.m_obj->addRef();
28+
if (m_obj != (_Obj*)0)
29+
m_obj->delRef();
2430
m_obj = obj.m_obj;
2531
return *this;
2632
}

0 commit comments

Comments
 (0)