1 #ifndef CODEGEN_CPPOUTPUT_HPP
2 #define CODEGEN_CPPOUTPUT_HPP
9 #include <boost/shared_ptr.hpp>
13 class DeclStage
{ public: enum Stage
{FORWARD
, DECL
, IMPL
}; };
15 struct GeneratedCode
{
16 std::ostringstream decls
;
17 std::ostringstream inits
;
18 std::ostringstream output
;
21 class CodegenCPPOutput
{
22 std::map
<std::string
, ActorAST
*> actors
;
23 std::map
<std::string
, ClassAST
*> classes
;
24 //std::vector<std::string> builtins;
25 std::vector
<VariableInfo
*> scopeStack
;
26 std::vector
<PrototypeAST
*> funStack
;
27 //std::vector<std::string> externFns;
28 //std::vector<PrototypeAST*> externFns;
29 std::string dontCareReturnVal
;
32 std::vector
<int> currentScopeCount
; //counts the number of elems local to the current scope
33 unsigned int currentFunGroup
;
39 std::string
nextTemp() {
41 sprintf(buffer
, "tmp%i__", tempNumber
);
43 return std::string(buffer
);
46 VariableInfo
* findVarInScope(const std::string
&name
) {
47 for (std::vector
<VariableInfo
*>::reverse_iterator iter
= scopeStack
.rbegin(), end
= scopeStack
.rend(); iter
!= end
; ++iter
) {
48 if ((*iter
)->name
== name
) {
56 //FIXME: This won't work with function overloading
58 bool checkIfExtern(const std::string
&fn
) {
59 for (std::vector
<PrototypeAST
*>::reverse_iterator iter
= funStack
.rbegin(), end
= funStack
.rend(); iter
!= end
; ++iter
) {
60 if ((*iter
)->name
== fn
) {
61 return (*iter
)->isExtern
;
67 // if (find(externFns.begin(), externFns.end(), fn) != externFns.end()) {
75 bool checkIfActor(const std::string
&s
) {
76 std::map
<std::string
, ActorAST
*>::iterator finder
= actors
.find(s
);
78 return (finder
!= actors
.end());
81 //void setupDontCare(const std::string &typeName) {
82 void setupDontCare(const TypeInfo
&ti
) {
83 //FIXME: Add in the position this happened
85 if (ti
.containerType
== ContainerType::Array
) {
86 dontCareReturnVal
= "NULL";
88 else if (ti
.declType
== "void") {
89 dontCareReturnVal
= "";
91 else if (ti
.declType
== "bool") {
92 dontCareReturnVal
= "false";
94 else if (ti
.declType
== "int") {
95 dontCareReturnVal
= "0";
97 else if (ti
.declType
== "double") {
98 dontCareReturnVal
= "0.0";
100 else if (ti
.declType
== "string") {
101 dontCareReturnVal
= "\"\"";
104 std::ostringstream msg
;
105 msg
<< "Unknown typename '" << ti
.declType
<< "'";
107 throw CompilerException(msg
.str());
111 bool isCopyDelete(const TypeInfo
&ti
) {
113 if (ti
.declType
== "void") {
116 else if (ti
.declType
== "bool") {
119 else if (ti
.declType
== "int") {
122 else if (ti
.declType
== "double") {
125 else if (ti
.declType
== "string") {
132 std::string
lookupAssocType(const TypeInfo
&ti
) {
133 //std::map<std::string, ActorAST*>::iterator finder = actors.find(ti.declType);
135 //if (finder != actors.end()) {
136 if (checkIfActor(ti
.declType
)) {
137 if (ti
.containerType
== ContainerType::Array
) {
138 return "std::vector<actorId_t>*";
145 std::ostringstream arrayType
;
146 if (ti
.containerType
== ContainerType::Array
) {
147 if ((ti
.declType
== "int") || (ti
.declType
== "float") || (ti
.declType
== "bool") || (ti
.declType
== "double") || (ti
.declType
== "void")) {
148 arrayType
<< "std::vector<" << ti
.declType
<< ">*";
150 else if (ti
.declType
== "string") {
151 arrayType
<< "std::vector<std::string>*";
154 arrayType
<< "std::vector<" << ti
.declType
<< "*>*";
156 return arrayType
.str();
159 if ((ti
.declType
== "int") || (ti
.declType
== "float") || (ti
.declType
== "bool") || (ti
.declType
== "double") || (ti
.declType
== "void")) {
160 arrayType
<< ti
.declType
;
162 else if (ti
.declType
== "string") {
163 arrayType
<< "std::string";
166 arrayType
<< ti
.declType
<< "*";
168 return arrayType
.str();
173 //std::string lookupPushForTypeAndBlock(const boost::shared_ptr<TypeInfo> ti, const std::string &block) {
174 std::string
lookupPushForTypeAndBlock(TypeInfo
&ti
, const std::string
&block
) {
175 std::ostringstream o
;
176 //std::map<std::string, ActorAST*>::iterator finder = actors.find(ti.get()->declType);
177 //if (finder != actors.end()) {
178 if (checkIfActor(ti
.declType
)) {
179 o
<< " tmpTU__.UInt32 = " << block
<< ";" << std::endl
;
181 else if (ti
.containerType
== ContainerType::Array
) {
182 //o << " tmpTU__.VoidPtr = " << block << ";" << std::endl;
183 std::string allocType
= lookupAssocType(ti
);
184 allocType
= allocType
.erase(allocType
.size()-1);
187 o
<< " tmpTU__.VoidPtr = new " << allocType
<< "();" << std::endl
;
188 if (ti
.containedTypes
[0].requiresCopyDelete()) {
189 o
<< " for (int i__=0; i__ < " << block
<< "->size(); ++i__) { (("
190 << lookupAssocType(ti
) << ")(tmpTU__.VoidPtr))->push_back(new "
191 << ti
.declType
<< "((*" << block
<< ")[i__])); }" << std::endl
;
194 o
<< " for (int i__=0; i__ < " << block
<< "->size(); ++i__) { (("
195 << lookupAssocType(ti
) << ")(tmpTU__.VoidPtr))->push_back((*"
196 << block
<< ")[i__]); }" << std::endl
;
199 else if (ti
.declType
== "int") {
200 o
<< " tmpTU__.UInt32 = " << block
<< ";" << std::endl
;
202 else if (ti
.declType
== "string") {
203 o
<< " tmpTU__.VoidPtr = strcpy(new char[" << block
<< ".size() + 1], " << block
<< ".c_str());" << std::endl
;
205 else if (ti
.declType
== "double") {
206 o
<< " tmpTU__.Double = " << block
<< ";" << std::endl
;
208 else if (ti
.declType
== "float") {
209 o
<< " tmpTU__.Float = " << block
<< ";" << std::endl
;
211 else if (ti
.declType
== "bool") {
212 o
<< " tmpTU__.Bool = " << block
<< ";" << std::endl
;
216 std::string allocType
= lookupAssocType(ti
);
217 allocType
= allocType
.erase(allocType
.size()-1);
218 o
<< " tmpTU__.VoidPtr = new " << allocType
<< "(" << block
<< ");" << std::endl
;
223 std::string
lookupPushForVar(const VariableInfo
*vi
) {
224 std::ostringstream o
;
225 if (vi
->type
.containerType
== ContainerType::Array
) {
226 o
<< " tmpTU__.VoidPtr = " << vi
->name
<< ";" << std::endl
;
228 else if (vi
->type
.declType
== "int") {
229 o
<< " tmpTU__.UInt32 = " << vi
->name
<< ";" << std::endl
;
231 else if (vi
->type
.declType
== "string") {
232 o
<< " tmpTU__.VoidPtr = strcpy(new char[" << vi
->name
<< ".size() + 1], " << vi
->name
<< ".c_str());" << std::endl
;
234 else if (vi
->type
.declType
== "double") {
235 o
<< " tmpTU__.Double = " << vi
->name
<< ";" << std::endl
;
237 else if (vi
->type
.declType
== "float") {
238 o
<< " tmpTU__.Float = " << vi
->name
<< ";" << std::endl
;
240 else if (vi
->type
.declType
== "bool") {
241 o
<< " tmpTU__.Bool = " << vi
->name
<< ";" << std::endl
;
244 //std::map<std::string, ActorAST*>::iterator finder = actors.find(vi->type.declType);
246 //if (finder != actors.end()) {
247 if (checkIfActor(vi
->type
.declType
)) {
248 o
<< " tmpTU__.UInt32 = " << vi
->name
<< ";" << std::endl
;
251 o
<< " tmpTU__.VoidPtr = " << vi
->name
<< ";" << std::endl
;
255 o
<< " actor__->heapStack.push_back(tmpTU__);" << std::endl
;
259 std::string
lookupPopForVar(const VariableInfo
*vi
) {
260 std::ostringstream o
;
261 if (vi
->type
.containerType
== ContainerType::Array
) {
262 o
<< " " << vi
->name
<< " = (" << lookupAssocType(vi
->type
) << ")(actor__->heapStack.back().VoidPtr); actor__->heapStack.pop_back();" << std::endl
;
264 else if (vi
->type
.declType
== "int") {
265 o
<< " " << vi
->name
<< " = actor__->heapStack.back().UInt32; actor__->heapStack.pop_back();" << std::endl
;
267 else if (vi
->type
.declType
== "string") {
268 o
<< " " << vi
->name
<< ".assign((char *)(actor__->heapStack.back().VoidPtr)); actor__->heapStack.pop_back(); delete((char *)(tmpTU__.VoidPtr));" << std::endl
;
270 else if (vi
->type
.declType
== "double") {
271 o
<< " " << vi
->name
<< " = actor__->heapStack.back().Double; actor__->heapStack.pop_back();" << std::endl
;
273 else if (vi
->type
.declType
== "float") {
274 o
<< " " << vi
->name
<< " = actor__->heapStack.back().Float; actor__->heapStack.pop_back();" << std::endl
;
276 else if (vi
->type
.declType
== "bool") {
277 o
<< " " << vi
->name
<< " = actor__->heapStack.back().Bool; actor__->heapStack.pop_back();" << std::endl
;
280 //std::map<std::string, ActorAST*>::iterator finder = actors.find(vi->type.declType);
282 //if (finder != actors.end()) {
283 if (checkIfActor(vi
->type
.declType
)) {
284 o
<< " " << vi
->name
<< " = (" << lookupAssocType(vi
->type
) << ")(actor__->heapStack.back().UInt32); actor__->heapStack.pop_back();" << std::endl
;
287 o
<< " " << vi
->name
<< " = (" << lookupAssocType(vi
->type
) << ")(actor__->heapStack.back().VoidPtr); actor__->heapStack.pop_back();" << std::endl
;
295 std::string lookupInternalType(const VariableInfo *vi) {
296 std::map<std::string, ActorAST*>::iterator finder = actors.find(vi->type.declType);
298 if (finder != actors.end()) {
299 if (vi->type.typeType == TypeType::Array) {
300 return "std::vector<actorId_t>*";
307 if (vi->type.typeType == TypeType::Array) {
308 std::ostringstream arrayType;
309 arrayType << "std::vector<" << lookupAssocType(vi->type.declType) << ">*";
310 return arrayType.str();
313 return lookupAssocType(vi->type.declType);
319 TypeInfo
lookupReturnTypeInfo(const CallExprAST
*ast
) {
320 //std::string returnVal("int");
322 for (std::vector
<PrototypeAST
*>::reverse_iterator iter
= funStack
.rbegin(),
323 end
= funStack
.rend(); iter
!= end
; ++iter
) {
324 //FIXME: This is insufficient for overloaded functions
325 if ((*iter
)->name
== ast
->name
) {
326 //TypeInfo ti((*iter)->type, TypeType::Scalar);
327 return (*iter
)->returnType
;
332 if (find(externFns.begin(), externFns.end(), ast->name) == externFns.end()) {
333 std::ostringstream msg;
334 msg << "Can not find function '" << ast->name << "'";
335 std::string outmsg = msg.str();
336 throw CompilerException(outmsg, ast->pos);
346 std::ostringstream msg
;
347 msg
<< "Can not find function '" << ast
->name
<< "'";
348 std::string outmsg
= msg
.str();
349 throw CompilerException(outmsg
, ast
->filepos
);
352 std::string
lookupReturnType(const CallExprAST
*ast
, const std::string
&container
) {
353 //std::string returnVal("int");
355 if (container
== "") {
356 for (std::vector
<PrototypeAST
*>::reverse_iterator iter
= funStack
.rbegin(), end
= funStack
.rend(); iter
!= end
; ++iter
) {
357 //FIXME: This is insufficient for overloaded functions
358 if ((*iter
)->name
== ast
->name
) {
359 //TypeInfo ti((*iter)->type, TypeType::Scalar);
360 return lookupAssocType((*iter
)->returnType
);
364 //TODO: Re-enable this
367 for (std::vector
<ASTNode
*>::iterator iter
= classes
[container
]->children
.begin(),
368 end
= classes
[container
]->children
.end(); iter
!= end
; ++iter
) {
370 FunctionAST
*fast
= dynamic_cast<FunctionAST
*>(*iter
);
372 //FIXME: This is insufficient for overloaded functions
373 PrototypeAST
*proto
= dynamic_cast<PrototypeAST
*>(fast
->children
[0]);
374 if (proto
->name
== ast
->name
) {
375 //TypeInfo ti((*iter)->type, TypeType::Scalar);
376 return lookupAssocType(proto
->returnType
);
382 std::ostringstream msg
;
383 msg
<< "Can not find function '" << ast
->name
<< "'";
384 std::string outmsg
= msg
.str();
385 throw CompilerException(outmsg
, ast
->filepos
);
388 if (find(externFns.begin(), externFns.end(), ast->name) == externFns.end()) {
389 std::ostringstream msg;
390 msg << "Can not find function '" << ast->name << "'";
391 std::string outmsg = msg.str();
392 throw CompilerException(outmsg, ast->pos);
402 std::string
outputResumeBlock() {
403 std::ostringstream output
;
406 int scopeStackSize
= scopeStack
.size() - 1;
407 for (unsigned int i
= scopeContainerId
; i
< currentScopeCount
.size(); ++i
) {
408 resumeCount
+= currentScopeCount
[i
];
411 output
<< "if (actor__->isResuming) {" << std::endl
;
412 for (int i
= 0; i
< resumeCount
; ++i
) {
413 VariableInfo
*vi
= scopeStack
[scopeStackSize
-i
];
414 output
<< lookupPopForVar(vi
);
416 output
<< " if (actor__->heapStack.size() == 0) {" << std::endl
;
417 output
<< " actor__->isResuming = false;" << std::endl
;
418 output
<< " }" << std::endl
;
419 output
<< "}" << std::endl
;
424 std::string
outputPauseBlock(bool decrement
) {
425 std::ostringstream output
;
428 int scopeStackSize
= scopeStack
.size() - 1;
429 for (unsigned int i
= scopeContainerId
; i
< currentScopeCount
.size(); ++i
) {
430 resumeCount
+= currentScopeCount
[i
];
434 output
<< "if (timeLeft__ > 0) {" << std::endl
;
435 output
<< " --timeLeft__;" << std::endl
;
436 output
<< "}" << std::endl
;
437 output
<< "else {" << std::endl
;
440 output
<< "if (timeLeft__ == 0) {" << std::endl
;
443 output
<< " actor__->parentThread->timeSliceEndTime = timeLeft__;" << std::endl
;
445 for (int i
= scopeStackSize
-resumeCount
+ 1; i
<= scopeStackSize
; ++i
) {
446 VariableInfo
*vi
= scopeStack
[i
];
447 output
<< lookupPushForVar(vi
);
449 output
<< " tmpTU__.UInt32 = " << (currentContId
-1) << ";" << std::endl
;
450 output
<< " actor__->heapStack.push_back(tmpTU__);" << std::endl
;
451 output
<< " return " << dontCareReturnVal
<< ";" << std::endl
;
452 output
<< "}" << std::endl
;
457 boost::shared_ptr
<TypeInfo
> resolveType(ASTNode
*ast
);
458 boost::shared_ptr
<GeneratedCode
> handleCall(CallExprAST
*ast
, const std::string
&container
, const std::string
&container_name
);
460 boost::shared_ptr
<GeneratedCode
> visit(ASTNode
*ast
); //catch all that will dispatch out to others
461 boost::shared_ptr
<GeneratedCode
> visit(NumberExprAST
*ast
);
462 boost::shared_ptr
<GeneratedCode
> visit(BooleanExprAST
*ast
);
463 boost::shared_ptr
<GeneratedCode
> visit(QuoteExprAST
*ast
);
464 boost::shared_ptr
<GeneratedCode
> visit(VariableExprAST
*ast
);
465 boost::shared_ptr
<GeneratedCode
> visit(VarDeclExprAST
*ast
);
466 boost::shared_ptr
<GeneratedCode
> visit(ArrayIndexedExprAST
*ast
);
467 //boost::shared_ptr<GeneratedCode> visit(ArrayDeclExprAST *ast);
468 boost::shared_ptr
<GeneratedCode
> visit(EndExprAST
*ast
);
469 boost::shared_ptr
<GeneratedCode
> visit(IfExprAST
*ast
);
470 boost::shared_ptr
<GeneratedCode
> visit(WhileExprAST
*ast
);
471 boost::shared_ptr
<GeneratedCode
> visit(BinaryExprAST
*ast
);
472 boost::shared_ptr
<GeneratedCode
> visit(CallExprAST
*ast
);
473 boost::shared_ptr
<GeneratedCode
> visit(ClassAST
*ast
, DeclStage::Stage stage
);
474 boost::shared_ptr
<GeneratedCode
> visit(ActorAST
*ast
, DeclStage::Stage stage
);
475 boost::shared_ptr
<GeneratedCode
> visit(PrototypeAST
*ast
, DeclStage::Stage stage
);
476 boost::shared_ptr
<GeneratedCode
> visit(ActionAST
*ast
, std::string actorName
, DeclStage::Stage stage
);
477 boost::shared_ptr
<GeneratedCode
> visit(FunctionAST
*ast
, DeclStage::Stage stage
);
478 boost::shared_ptr
<GeneratedCode
> visit(AppAST
*ast
);
480 std::string
translate(ASTNode
*ast
);
483 //builtins.push_back("int");