-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathCFunctionCallNode.cpp
More file actions
138 lines (103 loc) · 3.5 KB
/
CFunctionCallNode.cpp
File metadata and controls
138 lines (103 loc) · 3.5 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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
* CFunctionCallNode.cpp
* HyperCompiler
*
* Created by Uli Kusterer on 12.05.07.
* Copyright 2007 M. Uli Kusterer. All rights reserved.
*
*/
#include "CFunctionCallNode.h"
#include "CParseTree.h"
#include "CCodeBlock.h"
#include "CNodeTransformation.h"
#include "LEOInstructions.h"
#include "ForgeTypes.h"
#include "CParser.h"
namespace Carlson
{
CValueNode* CFunctionCallNode::Copy()
{
CFunctionCallNode * nodeCopy = new CFunctionCallNode( mParseTree, mIsCommand, mSymbolName, mLineNum );
std::vector<CValueNode*>::const_iterator itty;
for( itty = mParams.begin(); itty != mParams.end(); itty++ )
{
nodeCopy->AddParam( (*itty)->Copy() );
}
return nodeCopy;
}
void CFunctionCallNode::DebugPrint( std::ostream& destStream, size_t indentLevel )
{
INDENT_PREPARE(indentLevel);
destStream << indentChars << GetNodeName() << " \"" << mSymbolName << "\"" << std::endl
<< indentChars << "{" << std::endl;
std::vector<CValueNode*>::iterator itty;
for( itty = mParams.begin(); itty != mParams.end(); itty++ )
{
(*itty)->DebugPrint( destStream, indentLevel +1 );
}
destStream << indentChars << "}" << std::endl;
}
void CFunctionCallNode::AddParam( CValueNode* val )
{
mParams.push_back( val );
mParseTree->NodeWasAdded(val);
}
void CFunctionCallNode::Simplify()
{
CValueNode::Simplify();
std::vector<CValueNode*>::iterator itty;
for( itty = mParams.begin(); itty != mParams.end(); itty++ )
{
CValueNode * originalNode = *itty;
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 );
*itty = (CValueNode*)newNode;
}
}
}
void CFunctionCallNode::GenerateCode( CCodeBlock* inCodeBlock )
{
LEOInstructionID instructionID = INVALID_INSTR;
TBuiltInFunctionEntry *foundFunction = CParser::GetBuiltInFunctionWithName( mSymbolName );
if( foundFunction && foundFunction->mParamCount == mParams.size()
&& foundFunction->mParam1 == 0 && foundFunction->mParam2 == 0 )
{
instructionID = foundFunction->mInstructionID;
}
if( instructionID != INVALID_INSTR )
{
// Push the param on the stack:
size_t numParams = mParams.size();
for( size_t x = 0; x < numParams; ++x )
mParams[x]->GenerateCode( inCodeBlock );
inCodeBlock->GenerateOperatorInstruction( instructionID );
}
else
{
std::vector<CValueNode*>::reverse_iterator itty;
inCodeBlock->GeneratePushUnsetValueInstruction(); // Reserve space for the result.
// Push all params on stack (in reverse order!):
for( itty = mParams.rbegin(); itty != mParams.rend(); itty++ )
(*itty)->GenerateCode( inCodeBlock );
size_t numParams = mParams.size();
inCodeBlock->GeneratePushIntInstruction( (int)numParams, kLEOUnitNone );
// *** Call ***
inCodeBlock->GenerateFunctionCallInstruction( mIsCommand, mIsMessagePassing, mSymbolName );
// Clean up param count:
inCodeBlock->GeneratePopValueInstruction();
// Clean up params:
for( size_t x = 0; x < numParams; x++ )
inCodeBlock->GeneratePopValueInstruction();
// We leave the result on the stack.
}
}
void CFunctionCallNode::Visit( std::function<void(CNode*)> visitorBlock )
{
for( auto currParam : mParams )
currParam->Visit( visitorBlock );
CValueNode::Visit( visitorBlock );
}
} // namespace Carlson