-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathCWhileLoopNode.cpp
More file actions
88 lines (66 loc) · 2.67 KB
/
CWhileLoopNode.cpp
File metadata and controls
88 lines (66 loc) · 2.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*
* CWhileLoopNode.cpp
* HyperCompiler
*
* Created by Uli Kusterer on 19.05.07.
* Copyright 2007 M. Uli Kusterer. All rights reserved.
*
*/
#include "CWhileLoopNode.h"
#include "CCodeBlock.h"
#include "CNodeTransformation.h"
#include "LEOInterpreter.h"
namespace Carlson
{
void CWhileLoopNode::GenerateCode( CCodeBlock* inBlock )
{
if( !mCondition )
{
inBlock->GenerateParseErrorInstruction("Expected a condition after a repeat statement.", mFileName, mLineNum, SIZE_MAX);
return;
}
int32_t lineMarkerInstructionOffset = (int32_t) inBlock->GetNextInstructionOffset();
inBlock->GenerateLineMarkerInstruction( (int32_t) mLineNum, LEOFileIDForFileName(mFileName.c_str()) ); // Make sure debugger indicates condition as current line on every iteration.
// Push condition:
mCondition->GenerateCode(inBlock);
// Check condition, jump to end of loop if FALSE:
int32_t compareInstructionOffset = (int32_t) inBlock->GetNextInstructionOffset();
inBlock->GenerateJumpRelativeIfFalseInstruction( 0 );
// Generate loop commands:
CCodeBlockNode::GenerateCode( inBlock );
// At end of loop section, jump back to compare instruction:
int32_t jumpBackInstructionOffset = (int32_t) inBlock->GetNextInstructionOffset();
inBlock->GenerateJumpRelativeInstruction( lineMarkerInstructionOffset -jumpBackInstructionOffset );
// Retroactively fill in the address of the Else section in the if's jump instruction:
int32_t loopEndOffset = (int32_t) inBlock->GetNextInstructionOffset();
inBlock->SetJumpAddressOfInstructionAtIndex( compareInstructionOffset, loopEndOffset -compareInstructionOffset );
}
void CWhileLoopNode::Simplify()
{
if( !mCondition )
return;
CValueNode * originalNode = mCondition;
originalNode->Simplify(); // Give subnodes a chance to apply transformations first. Might expose simpler sub-nodes we can then simplify.
CNode* newNode = CNodeTransformationBase::Apply( originalNode ); // Returns either originalNode, or a totally new object, in which case we delete the old one.
if( newNode != originalNode )
{
assert( dynamic_cast<CValueNode*>(newNode) != NULL );
mCondition = (CValueNode*)newNode;
}
CCodeBlockNode::Simplify();
}
void CWhileLoopNode::Visit( std::function<void(CNode*)> visitorBlock )
{
if( mCondition )
mCondition->Visit(visitorBlock);
CCodeBlockNode::Visit(visitorBlock);
}
void CWhileLoopNode::DebugPrint( std::ostream& destStream, size_t indentLevel )
{
INDENT_PREPARE(indentLevel);
destStream << indentChars << "While" << std::endl << indentChars << "(" << std::endl;
mCondition->DebugPrint( destStream, indentLevel +1 );
destStream << indentChars << ")" << std::endl;
DebugPrintInner( destStream, indentLevel );
}
} /*Carlson*/