1 #include "codegen_cppoutput.hpp"
3 #include <boost/shared_ptr.hpp>
7 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::handleCall(CallExprAST
*ast
, const std::string
&container
, const std::string
&container_name
) {
8 boost::shared_ptr
<GeneratedCode
> gc(new GeneratedCode
), gc_temp
;
9 std::vector
<boost::shared_ptr
<GeneratedCode
> > gc_args
;
10 bool isExtern
= checkIfExtern(ast
->name
);
12 for (int i
= 0, j
= ast
->children
.size(); i
!= j
; ++i
) {
13 gc_args
.push_back(visit (ast
->children
[i
]));
16 for (int i
= 0, j
= ast
->children
.size(); i
!= j
; ++i
) {
18 // gc.get()->inits << ", ";
19 if (gc_args
[i
].get()->decls
.str() != "") {
20 gc
.get()->decls
<< gc_args
[i
].get()->decls
.str();
22 if (gc_args
[i
].get()->inits
.str() != "") {
23 gc
.get()->inits
<< gc_args
[i
].get()->inits
.str();
27 if (ast
->name
== "return") {
28 //if this is a return call, we need to clear our scope stack up to where we came from
30 if (gc_args
.size() > 1) {
31 throw CompilerException("Too many arguments in return", ast
->filepos
);
34 int unwindAmount
= currentScopeCount
.back();
35 for (int i
= 0; i
< unwindAmount
; ++i
) {
36 VariableInfo
*vi
= scopeStack
[scopeStack
.size()-1-i
];
37 if ((vi
->type
.requiresCopyDelete())&&(!checkIfActor(vi
->type
.declType
))) {
38 //since it's a return, we don't want to delete what we're returning, so be careful. This isn't the best way to do this, so I'm open to suggestions.
39 if ((gc_args
.size() == 1) && (vi
->name
!= gc_args
[0].get()->output
.str())) {
40 gc
.get()->inits
<< "if (" << vi
->name
<< " != NULL) {" << std::endl
;
41 gc
.get()->inits
<< " delete(" << vi
->name
<< ");" << std::endl
;
42 gc
.get()->inits
<< "}" << std::endl
;
47 gc
.get()->output
<< "return (";
48 for (int i
= 0, j
= ast
->children
.size(); i
!= j
; ++i
) {
50 gc
.get()->output
<< ", ";
52 if (gc_args
[i
].get()->output
.str() != "") {
53 gc
.get()->output
<< gc_args
[i
].get()->output
.str();
56 gc
.get()->output
<< ")";
58 //"return" is a special case, so get out of here
62 std::string tmpName
= nextTemp();
63 std::string retType
= lookupReturnType(ast
, container
);
64 if (retType
!= "void") {
65 gc
.get()->decls
<< retType
<< " " << tmpName
<< ";" << std::endl
;
68 gc
.get()->inits
<< "case(" << currentContId
<< "):" << std::endl
;
71 gc
.get()->inits
<< outputResumeBlock();
74 gc
.get()->inits
<< "actor__->parentThread->timeSliceEndTime = timeLeft__;" << std::endl
;
77 if (retType
!= "void") {
78 gc
.get()->inits
<< tmpName
<< " = ";
79 if (container_name
!= "") {
80 gc
.get()->inits
<< container_name
<< "->";
82 gc
.get()->inits
<< ast
->name
<< "(";
85 if (container_name
!= "") {
86 gc
.get()->inits
<< container_name
<< "->";
88 gc
.get()->inits
<< ast
->name
<< "(";
91 for (int i
= 0, j
= ast
->children
.size(); i
!= j
; ++i
) {
93 gc
.get()->inits
<< ", ";
95 if (gc_args
[i
].get()->output
.str() != "") {
96 gc
.get()->inits
<< gc_args
[i
].get()->output
.str();
101 if (ast
->children
.size() > 0) {
102 gc
.get()->inits
<< ", ";
104 gc
.get()->inits
<< "actor__";
107 gc
.get()->inits
<< ");" << std::endl
;
109 //since the external call will no decrement the timeslice, we need to do it manually
110 gc
.get()->inits
<< "--timeLeft__;" << std::endl
;
113 gc
.get()->inits
<< "timeLeft__ = actor__->parentThread->timeSliceEndTime;" << std::endl
;
115 gc
.get()->inits
<< outputPauseBlock(false);
117 if (retType
!= "void") {
118 gc
.get()->output
<< tmpName
;
124 //catch all that will dispatch out to others
125 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::visit(ASTNode
*ast
) {
126 boost::shared_ptr
<GeneratedCode
> gc
;
128 NumberExprAST
*neast
;
129 BooleanExprAST
*boeast
;
131 VariableExprAST
*veast
;
132 VarDeclExprAST
*vdeast
;
133 ArrayIndexedExprAST
*aieast
;
134 //ArrayDeclExprAST *adeast;
138 BinaryExprAST
*beast
;
148 gc
= boost::shared_ptr
<GeneratedCode
>(new GeneratedCode
);
151 //Number, Variable, ArrayIndexed, Binary, Quote, Call, DefFun, End, VarDecl, If, While
152 switch (ast
->type()) {
153 case (NodeType::Number
) :
154 neast
= dynamic_cast<NumberExprAST
*>(ast
);
156 printf("FIXME: Number compiler exception\n");
160 case (NodeType::Boolean
) :
161 boeast
= dynamic_cast<BooleanExprAST
*>(ast
);
162 if (boeast
== NULL
) {
163 printf("FIXME: Number compiler exception\n");
167 case (NodeType::Variable
) :
168 veast
= dynamic_cast<VariableExprAST
*>(ast
);
170 printf("FIXME: Variable compiler exception\n");
174 case (NodeType::ArrayIndexed
) :
175 aieast
= dynamic_cast<ArrayIndexedExprAST
*>(ast
);
176 if (aieast
== NULL
) {
177 printf("FIXME: Array indexed compiler exception\n");
181 case (NodeType::Binary
) :
182 beast
= dynamic_cast<BinaryExprAST
*>(ast
);
184 printf("FIXME: Variable compiler exception\n");
188 case (NodeType::Quote
) :
189 qeast
= dynamic_cast<QuoteExprAST
*>(ast
);
191 printf("FIXME: Variable compiler exception\n");
195 case (NodeType::Call
) :
196 ceast
= dynamic_cast<CallExprAST
*>(ast
);
198 printf("FIXME: Call compiler exception\n");
202 case (NodeType::End
) :
203 eeast
= dynamic_cast<EndExprAST
*>(ast
);
205 printf("FIXME: End compiler exception\n");
209 case (NodeType::VarDecl
) :
210 vdeast
= dynamic_cast<VarDeclExprAST
*>(ast
);
211 if (vdeast
== NULL
) {
212 printf("FIXME: VarDecl compiler exception\n");
216 case (NodeType::If
) :
217 ieast
= dynamic_cast<IfExprAST
*>(ast
);
219 printf("FIXME: If compiler exception\n");
224 case (NodeType::While
) :
225 weast
= dynamic_cast<WhileExprAST
*>(ast
);
227 printf("FIXME: While compiler exception\n");
231 case (NodeType::Action
) :
232 actast
= dynamic_cast<ActionAST
*>(ast
);
233 if (actast
== NULL
) {
234 printf("FIXME: action compiler exception\n");
238 case (NodeType::Function
) :
239 funast
= dynamic_cast<FunctionAST
*>(ast
);
240 if (funast
== NULL
) {
241 printf("FIXME: function compiler exception\n");
245 case (NodeType::Actor
) :
246 actorast
= dynamic_cast<ActorAST
*>(ast
);
247 if (actorast
== NULL
) {
248 printf("FIXME: actor compiler exception\n");
250 gc
= visit(actorast
);
252 case (NodeType::Class
) :
253 classast
= dynamic_cast<ClassAST
*>(ast
);
254 if (classast
== NULL
) {
255 printf("FIXME: class compiler exception\n");
257 gc
= visit(classast
);
259 case (NodeType::App
) :
260 appast
= dynamic_cast<AppAST
*>(ast
);
261 if (appast
== NULL
) {
262 printf("FIXME: app compiler exception\n");
267 throw CompilerException("Unknown element", ast
->filepos
);
273 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::visit(NumberExprAST
*ast
) {
274 boost::shared_ptr
<GeneratedCode
> gc(new GeneratedCode
);
276 gc
.get()->output
<< ast
->val
;
280 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::visit(QuoteExprAST
*ast
) {
281 boost::shared_ptr
<GeneratedCode
> gc(new GeneratedCode
);
283 gc
.get()->output
<< "\"" << ast
->val
<< "\"";
287 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::visit(BooleanExprAST
*ast
) {
288 boost::shared_ptr
<GeneratedCode
> gc(new GeneratedCode
);
290 if (ast
->val
== true) {
291 gc
.get()->output
<< "true";
294 gc
.get()->output
<< "false";
299 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::visit(VariableExprAST
*ast
) {
300 boost::shared_ptr
<GeneratedCode
> gc(new GeneratedCode
);
302 //TODO: Putting these here for now, but we should handle keywords in a more special place in the future
303 if ((ast
->name
== "return") || (ast
->name
== "done")) {
305 //if this is a return call, we need to clear our scope stack up to where we came from
306 int unwindAmount
= currentScopeCount
.back();
307 for (int i
= 0; i
< unwindAmount
; ++i
) {
308 VariableInfo
*vi
= scopeStack
[scopeStack
.size()-1-i
];
309 if ((vi
->type
.requiresCopyDelete())&&(!checkIfActor(vi
->type
.declType
))) {
310 gc
.get()->output
<< "if (" << vi
->name
<< " != NULL) {" << std::endl
;
311 gc
.get()->output
<< " delete(" << vi
->name
<< ");" << std::endl
;
312 gc
.get()->output
<< "}" << std::endl
;
316 if (ast
->name
== "return") {
317 gc
.get()->output
<< "--timeLeft__;" << std::endl
;
318 gc
.get()->output
<< "actor__->parentThread->timeSliceEndTime = timeLeft__;" << std::endl
;
319 gc
.get()->output
<< "actor__->actorState = ActorState::WAITING_FOR_ACTION;" << std::endl
;
320 gc
.get()->output
<< "return; " << std::endl
;
322 else if (ast
->name
== "done") {
323 gc
.get()->output
<< "--timeLeft__;" << std::endl
;
324 gc
.get()->output
<< "actor__->parentThread->timeSliceEndTime = timeLeft__;" << std::endl
;
325 gc
.get()->output
<< "actor__->actorState = ActorState::DELETED;" << std::endl
;
326 gc
.get()->output
<< "return; " << std::endl
;
332 VariableInfo
*vi
= findVarInScope(ast
->name
);
334 std::ostringstream oss
;
335 oss
<< "Unknown variable '" << ast
->name
<< "'";
336 throw CompilerException(oss
.str(), ast
->filepos
);
339 if (vi
->scopeType
== ScopeType::Actor
) {
340 if (vi
->name
== "this") {
341 gc
.get()->output
<< "actor__->actorId";
344 gc
.get()->output
<< "actor__->" << ast
->name
;
348 gc
.get()->output
<< ast
->name
;
353 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::visit(VarDeclExprAST
*ast
) {
354 boost::shared_ptr
<GeneratedCode
> gc(new GeneratedCode
);
356 VariableInfo
*vi
= ast
->vi
; //new VariableInfo(ast->name, ast->declType, ContainerType::Scalar, ScopeType::CodeBlock);
358 if (vi
->type
.containerType
== ContainerType::Scalar
) {
359 std::map
<std::string
, ActorAST
*>::iterator finder
= actors
.find(vi
->type
.declType
);
361 if (finder
!= actors
.end()) {
363 std::string actorTemp
= nextTemp();
364 gc
.get()->decls
<< "actorId_t " << vi
->name
<< ";" << std::endl
;
365 gc
.get()->inits
<< vi
->type
.declType
<< " *" << actorTemp
<< ";" << std::endl
;
366 gc
.get()->output
<< "{ " << actorTemp
<< " = new " << vi
->type
.declType
<< "();" << std::endl
;
367 if (finder
->second
->isIsolated
) {
368 gc
.get()->output
<< " actor__->parentThread->ScheduleNewIsolatedActor(" << actorTemp
<< ");" << std::endl
;
371 gc
.get()->output
<< " actor__->parentThread->ScheduleNewActor(" << actorTemp
<< ");" << std::endl
;
373 gc
.get()->output
<< " " << vi
->name
<< " = " << actorTemp
<< "->actorId; }" << std::endl
;
376 gc
.get()->decls
<< "actorId_t " << vi
->name
<< ";" << std::endl
;
380 gc
.get()->decls
<< lookupAssocType(vi
->type
) << " " << vi
->name
<< ";" << std::endl
;
383 std::string allocType
= lookupAssocType(vi
->type
);
384 allocType
= allocType
.erase(allocType
.size()-1);
386 gc
.get()->output
<< vi
->name
<< " = new " << allocType
<< "();" << std::endl
;
388 gc
.get()->output
<< vi
->name
;
391 else if (vi
->type
.containerType
== ContainerType::Array
) {
392 std::map
<std::string
, ActorAST
*>::iterator finder
= actors
.find(vi
->type
.declType
);
394 if (finder
!= actors
.end()) {
396 std::string tmpName
= nextTemp();
397 gc
.get()->decls
<< "int " << tmpName
<< ";" << std::endl
;
399 std::string actorTemp
= nextTemp();
400 std::string loopTemp
= nextTemp();
401 gc
.get()->decls
<< vi
->type
.declType
<< " *" << actorTemp
<< ";" << std::endl
;
403 gc
.get()->decls
<< "std::vector<actorId_t> *" << vi
->name
<< ";" << std::endl
;
405 gc
.get()->output
<< tmpName
<< " = ";
407 if (vi
->size
!= NULL
) {
408 boost::shared_ptr
<GeneratedCode
> gc_temp
= visit (vi
->size
);
409 if (gc_temp
.get()->decls
.str() != "") {
410 gc
.get()->decls
<< gc_temp
.get()->decls
.str();
412 if (gc_temp
.get()->inits
.str() != "") {
413 gc
.get()->output
<< gc_temp
.get()->inits
.str();
415 if (gc_temp
.get()->output
.str() != "") {
416 gc
.get()->output
<< gc_temp
.get()->output
.str();
420 gc
.get()->output
<< "0";
422 gc
.get()->output
<< ";" << std::endl
;
423 gc
.get()->output
<< vi
->name
<< " = new std::vector<actorId_t>(" << tmpName
<< ");" << std::endl
;
425 gc
.get()->output
<< "for (int " << loopTemp
<< "=0; " << loopTemp
<< " < " << tmpName
<< "; ++" << loopTemp
<< ") {" << std::endl
;
426 gc
.get()->output
<< " " << actorTemp
<< " = new " << vi
->type
.declType
<< "();" << std::endl
;
427 if (finder
->second
->isIsolated
) {
428 gc
.get()->output
<< " actor__->parentThread->ScheduleNewIsolatedActor(" << actorTemp
<< ");" << std::endl
;
431 gc
.get()->output
<< " actor__->parentThread->ScheduleNewActor(" << actorTemp
<< ");" << std::endl
;
433 gc
.get()->output
<< " (*" << vi
->name
<< ")[" << loopTemp
<< "] = " << actorTemp
<< "->actorId;" << std::endl
;
434 gc
.get()->output
<< "}" << std::endl
;
437 gc
.get()->decls
<< "std::vector<actorId_t> *" << vi
->name
<< ";" << std::endl
;
438 gc
.get()->output
<< vi
->name
<< " = new std::vector<actorId_t>(";
439 if (vi
->size
!= NULL
) {
440 boost::shared_ptr
<GeneratedCode
> gc_temp
= visit (vi
->size
);
441 if (gc_temp
.get()->decls
.str() != "") {
442 gc
.get()->decls
<< gc_temp
.get()->decls
.str();
444 if (gc_temp
.get()->inits
.str() != "") {
445 gc
.get()->output
<< gc_temp
.get()->inits
.str();
447 if (gc_temp
.get()->output
.str() != "") {
448 gc
.get()->output
<< gc_temp
.get()->output
.str();
452 gc
.get()->output
<< "0";
454 gc
.get()->output
<< ");" << std::endl
;
458 gc
.get()->decls
<< lookupAssocType(vi
->type
) << " " << vi
->name
<< ";" << std::endl
;
459 std::string allocType
= lookupAssocType(vi
->type
);
460 allocType
= allocType
.erase(allocType
.size()-1); //TRIM off the trailing '*'
461 gc
.get()->output
<< vi
->name
<< " = new " << allocType
<< "(";
462 if (vi
->size
!= NULL
) {
463 boost::shared_ptr
<GeneratedCode
> gc_temp
= visit (vi
->size
);
464 if (gc_temp
.get()->decls
.str() != "") {
465 gc
.get()->decls
<< gc_temp
.get()->decls
.str();
467 if (gc_temp
.get()->inits
.str() != "") {
468 gc
.get()->output
<< gc_temp
.get()->inits
.str();
470 if (gc_temp
.get()->output
.str() != "") {
471 gc
.get()->output
<< gc_temp
.get()->output
.str();
475 gc
.get()->output
<< "0";
477 gc
.get()->output
<< ")";
479 //FIXME? Would you ever follow an array decl with an assignment? If so, we should probably check for that
482 ++(currentScopeCount
.back());
483 scopeStack
.push_back(vi
);
487 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::visit(ArrayIndexedExprAST
*ast
) {
488 boost::shared_ptr
<GeneratedCode
> gc(new GeneratedCode
);
490 VariableInfo
*vi
= findVarInScope(ast
->name
);
492 std::ostringstream oss
;
493 oss
<< "Unknown array variable '" << ast
->name
<< "'";
494 throw CompilerException(oss
.str(), ast
->filepos
);
496 else if (vi
->type
.containerType
!= ContainerType::Array
) {
497 std::ostringstream oss
;
498 oss
<< "Variable '" << ast
->name
<< "' is not of an array type";
499 throw CompilerException(oss
.str(), ast
->filepos
);
501 if (vi
->scopeType
== ScopeType::Actor
) {
502 gc
.get()->output
<< "(*(actor__->" << ast
->name
<< "))";
505 gc
.get()->output
<< "(*" << ast
->name
<< ")";
507 gc
.get()->output
<< "[";
508 boost::shared_ptr
<GeneratedCode
> gc_temp
= visit (ast
->children
[0]);
509 if (gc_temp
.get()->decls
.str() != "") {
510 gc
.get()->decls
<< gc_temp
.get()->decls
.str();
512 if (gc_temp
.get()->inits
.str() != "") {
513 gc
.get()->output
<< gc_temp
.get()->inits
.str();
515 if (gc_temp
.get()->output
.str() != "") {
516 gc
.get()->output
<< gc_temp
.get()->output
.str();
518 gc
.get()->output
<< "]";
523 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::visit(EndExprAST
*ast
) {
525 boost::shared_ptr
<GeneratedCode
> gc(new GeneratedCode
);
530 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::visit(IfExprAST
*ast
) {
531 boost::shared_ptr
<GeneratedCode
> gc(new GeneratedCode
);
532 boost::shared_ptr
<GeneratedCode
> gc_cond
;
534 std::string condTemp
= nextTemp();
536 gc
.get()->decls
<< "bool " << condTemp
<< ";" << std::endl
;
538 gc_cond
= visit (ast
->children
[0]);
539 if (gc_cond
.get()->decls
.str() != "") {
540 gc
.get()->decls
<< gc_cond
.get()->decls
.str();
542 if (gc_cond
.get()->inits
.str() != "") {
543 gc
.get()->output
<< gc_cond
.get()->inits
.str();
546 if (gc_cond
.get()->output
.str() != "") {
547 gc
.get()->output
<< condTemp
<< " = " << gc_cond
.get()->output
.str() << ";" << std::endl
;
550 gc
.get()->output
<< "if (" << condTemp
<< ") {" << std::endl
;
552 for (std::vector
<ASTNode
*>::iterator iter
= ast
->children
[1]->children
.begin(),
553 end
= ast
->children
[1]->children
.end(); iter
!= end
; ++iter
) {
555 boost::shared_ptr
<GeneratedCode
> gc_temp
= visit (*iter
);
556 if (gc_temp
.get()->decls
.str() != "") {
557 gc
.get()->decls
<< gc_temp
.get()->decls
.str();
559 if (gc_temp
.get()->inits
.str() != "") {
560 gc
.get()->output
<< gc_temp
.get()->inits
.str();
562 if (gc_temp
.get()->output
.str() != "") {
563 gc
.get()->output
<< gc_temp
.get()->output
.str();
565 gc
.get()->output
<< ";" << std::endl
;
567 gc
.get()->output
<< "}";
568 if (ast
->children
[2]->children
.size() > 0) {
569 gc
.get()->output
<< "else {" << std::endl
;
570 for (std::vector
<ASTNode
*>::iterator iter
= ast
->children
[2]->children
.begin(),
571 end
= ast
->children
[2]->children
.end(); iter
!= end
; ++iter
) {
573 boost::shared_ptr
<GeneratedCode
> gc_temp
= visit (*iter
);
574 if (gc_temp
.get()->decls
.str() != "") {
575 gc
.get()->decls
<< gc_temp
.get()->decls
.str();
577 if (gc_temp
.get()->inits
.str() != "") {
578 gc
.get()->output
<< gc_temp
.get()->inits
.str();
580 if (gc_temp
.get()->output
.str() != "") {
581 gc
.get()->output
<< gc_temp
.get()->output
.str();
583 gc
.get()->output
<< ";" << std::endl
;
585 gc
.get()->output
<< "}" << std::endl
;
591 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::visit(WhileExprAST
*ast
) {
592 boost::shared_ptr
<GeneratedCode
> gc(new GeneratedCode
);
593 boost::shared_ptr
<GeneratedCode
> gc_cond
, gc_temp
;
595 std::string condTemp
= nextTemp();
597 gc
.get()->decls
<< "bool " << condTemp
<< ";" << std::endl
;
598 gc
.get()->output
<< "case(" << currentContId
<< "):" << std::endl
;
600 gc
.get()->output
<< (outputResumeBlock());
602 gc_cond
= visit (ast
->children
[0]);
603 if (gc_cond
.get()->decls
.str() != "") {
604 gc
.get()->decls
<< gc_cond
.get()->decls
.str();
606 if (gc_cond
.get()->inits
.str() != "") {
607 gc
.get()->output
<< gc_cond
.get()->inits
.str();
609 if (gc_cond
.get()->output
.str() != "") {
610 gc
.get()->output
<< condTemp
<< " = " << gc_cond
.get()->output
.str() << ";" << std::endl
;
612 gc
.get()->output
<< "while (" << condTemp
<< ") {" << std::endl
;
613 gc
.get()->output
<< (outputPauseBlock(true));
614 for (std::vector
<ASTNode
*>::iterator iter
= ast
->children
[1]->children
.begin(),
615 end
= ast
->children
[1]->children
.end(); iter
!= end
; ++iter
) {
616 gc_temp
= visit (*iter
);
617 if (gc_temp
.get()->decls
.str() != "") {
618 gc
.get()->decls
<< gc_temp
.get()->decls
.str();
620 if (gc_temp
.get()->inits
.str() != "") {
621 gc
.get()->output
<< gc_temp
.get()->inits
.str();
623 if (gc_temp
.get()->output
.str() != "") {
624 gc
.get()->output
<< gc_temp
.get()->output
.str();
627 gc
.get()->output
<< ";" << std::endl
;
629 gc_cond
= visit (ast
->children
[0]);
630 if (gc_cond
.get()->decls
.str() != "") {
631 gc
.get()->decls
<< gc_cond
.get()->decls
.str();
633 if (gc_cond
.get()->inits
.str() != "") {
634 gc
.get()->output
<< gc_cond
.get()->inits
.str();
636 if (gc_cond
.get()->output
.str() != "") {
637 gc
.get()->output
<< condTemp
<< " = " << gc_cond
.get()->output
.str() << ";" << std::endl
;
640 gc
.get()->output
<< "}";
644 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::visit(BinaryExprAST
*ast
) {
645 boost::shared_ptr
<GeneratedCode
> gc(new GeneratedCode
);
646 boost::shared_ptr
<GeneratedCode
> gc_temp
;
648 if (ast
->op
== "::") {
649 CallExprAST
*ceast
= dynamic_cast<CallExprAST
*>(ast
->children
[1]);
650 VariableExprAST
*veast
= dynamic_cast<VariableExprAST
*>(ast
->children
[0]);
651 ArrayIndexedExprAST
*aieast
= dynamic_cast<ArrayIndexedExprAST
*>(ast
->children
[0]);
656 std::ostringstream msg
;
657 msg
<< "Can't build message, right hand side is type: " << ast
->children
[1]->type();
658 throw CompilerException(msg
.str(), ast
->filepos
);
661 if ((veast
== NULL
) && (aieast
== NULL
)) {
662 std::ostringstream msg
;
663 msg
<< "Can't build message, left hand side is type: " << ast
->children
[0]->type();
664 throw CompilerException(msg
.str(), ast
->filepos
);
666 else if (veast
!= NULL
) {
667 vi
= findVarInScope(veast
->name
);
669 std::ostringstream oss
;
670 oss
<< "Unknown variable for message '" << veast
->name
<< "'";
671 throw CompilerException(oss
.str(), veast
->filepos
);
674 else { //if (aieast != NULL) {
675 vi
= findVarInScope(aieast
->name
);
677 std::ostringstream oss
;
678 oss
<< "Unknown variable for message '" << aieast
->name
<< "'";
679 throw CompilerException(oss
.str(), aieast
->filepos
);
683 //int argSize = ceast->args.size();
684 std::string msgName
= nextTemp();
685 std::string actorIfLocal
= nextTemp();
686 std::string msgArray
;
688 gc
.get()->decls
<< "Actor *" << actorIfLocal
<< ";" << std::endl
;
690 gc
.get()->output
<< actorIfLocal
<< " = actor__->parentThread->ActorIfLocal(";
691 gc_temp
= visit (ast
->children
[0]);
693 if (gc_temp
.get()->decls
.str() != "") {
694 gc
.get()->decls
<< gc_temp
.get()->decls
.str();
696 if (gc_temp
.get()->inits
.str() != "") {
697 gc
.get()->output
<< gc_temp
.get()->inits
.str();
699 if (gc_temp
.get()->output
.str() != "") {
700 gc
.get()->output
<< gc_temp
.get()->output
.str();
702 gc
.get()->output
<< ", actor__);" << std::endl
;
704 gc
.get()->output
<< "if ((" << actorIfLocal
<< " == NULL) || (" << actorIfLocal
<< "->actorState != ActorState::WAITING_FOR_ACTION)) {" << std::endl
;
705 gc
.get()->decls
<< "Message " << msgName
<< ";" << std::endl
;
706 gc
.get()->output
<< " " << msgName
<< ".recipient = ";
708 gc_temp
= visit (ast
->children
[0]);
709 if (gc_temp
.get()->decls
.str() != "") {
710 gc
.get()->decls
<< gc_temp
.get()->decls
.str();
712 if (gc_temp
.get()->inits
.str() != "") {
713 gc
.get()->output
<< gc_temp
.get()->inits
.str();
715 if (gc_temp
.get()->output
.str() != "") {
716 gc
.get()->output
<< gc_temp
.get()->output
.str();
719 gc
.get()->output
<< ";" << std::endl
;
720 gc
.get()->output
<< " " << msgName
<< ".numArgs = " << ceast
->children
.size() << ";" << std::endl
;
721 gc
.get()->output
<< " " << msgName
<< ".messageType = MessageType::ACTION_MESSAGE;" << std::endl
;
722 gc
.get()->output
<< " " << msgName
<< ".task = &" << vi
->type
.declType
<< "__" << ceast
->name
<< "_action;" << std::endl
;
724 //std::cout << "arg size: " << ceast->args.size() << std::endl;
725 if (ceast
->children
.size() > 4 ) {
726 msgArray
= nextTemp();
727 gc
.get()->decls
<< "std::vector<TypeUnion> *" << msgArray
<< " = new std::vector<TypeUnion>();" << std::endl
;
729 for (unsigned int i
= 0; i
< ceast
->children
.size(); ++i
) {
730 //boost::shared_ptr<TypeInfo> ti = resolveType(ceast->children[i]);
732 boost::shared_ptr
<GeneratedCode
> gc_temp
= visit (ceast
->children
[i
]);
733 if (gc_temp
.get()->decls
.str() != "") {
734 gc
.get()->decls
<< gc_temp
.get()->decls
.str();
736 if (gc_temp
.get()->inits
.str() != "") {
737 gc
.get()->output
<< gc_temp
.get()->inits
.str();
739 if (gc_temp
.get()->output
.str() != "") {
740 //gc.get()->output << gc_temp.get()->output.str();
741 gc
.get()->output
<< " " << lookupPushForTypeAndBlock
742 (ceast
->children
[i
]->programmaticType
, gc_temp
.get()->output
.str());
744 if (ceast
->children
.size() > 4 ) {
745 gc
.get()->output
<< " " << msgArray
<< "->push_back(tmpTU__);" << std::endl
;
748 gc
.get()->output
<< " " << msgName
<< ".arg[" << i
<< "] = tmpTU__;" << std::endl
;
752 if (ceast
->children
.size() > 4 ) {
753 gc
.get()->output
<< " " << msgName
<< ".arg[0].VoidPtr = " << msgArray
<< ";" << std::endl
;
756 gc
.get()->output
<< "actor__->parentThread->SendMessage(" << msgName
<< ");" << std::endl
;
757 gc
.get()->output
<< "}" << std::endl
;
758 gc
.get()->output
<< "else {" << std::endl
;
760 for (unsigned int i
= 0; i
< ceast
->children
.size(); ++i
) {
761 //boost::shared_ptr<TypeInfo> ti = resolveType(ceast->children[i]);
762 //gc.get()->output << "tmpTU__.UInt32 = ";
764 boost::shared_ptr
<GeneratedCode
> gc_temp
= visit (ceast
->children
[i
]);
765 if (gc_temp
.get()->decls
.str() != "") {
766 gc
.get()->decls
<< gc_temp
.get()->decls
.str();
768 if (gc_temp
.get()->inits
.str() != "") {
769 gc
.get()->output
<< gc_temp
.get()->inits
.str();
771 if (gc_temp
.get()->output
.str() != "") {
772 //gc.get()->output << gc_temp.get()->output.str();
773 gc
.get()->output
<< " " << lookupPushForTypeAndBlock
774 (ceast
->children
[i
]->programmaticType
, gc_temp
.get()->output
.str());
775 //gc.get()->output << " " << msgName << ".arg[" << i << "] = tmpTU__;" << std::endl;
778 gc
.get()->output
<< ";" << std::endl
;
779 gc
.get()->output
<< actorIfLocal
<< "->heapStack.push_back(tmpTU__);" << std::endl
;
782 gc
.get()->output
<< actorIfLocal
<< "->task = &" << vi
->type
.declType
<< "__" << ceast
->name
<< "_action;" << std::endl
;
783 gc
.get()->output
<< actorIfLocal
<< "->actorState = ActorState::ACTIVE;" << std::endl
;
785 gc
.get()->output
<< "actor__->parentThread->hotActor = " << actorIfLocal
<< ";" << std::endl
;
786 gc
.get()->output
<< "if (" << actorIfLocal
<< "->runQueueRevId != actor__->parentThread->runQueueRevId) {" << std::endl
;
787 gc
.get()->output
<< " actor__->parentThread->runningActors.push_back(" << actorIfLocal
<< ");" << std::endl
;
788 gc
.get()->output
<< " " << actorIfLocal
<< "->runQueueRevId = actor__->parentThread->runQueueRevId;" << std::endl
;
789 gc
.get()->output
<< " }" << std::endl
;
790 gc
.get()->output
<< "}" << std::endl
;
792 else if (ast
->op
== ".") {
793 VariableExprAST
*veast
= dynamic_cast<VariableExprAST
*>(ast
->children
[1]);
794 CallExprAST
*ceast
= dynamic_cast<CallExprAST
*>(ast
->children
[1]);
795 if ((veast
== NULL
) && (ceast
== NULL
)) {
796 std::cout
<< "Can't use '.' in this context, is type: " << ast
->children
[1]->type() << std::endl
;
800 VariableExprAST
*lhs_ast
= dynamic_cast<VariableExprAST
*>(ast
->children
[0]);
801 //ArrayIndexedExprAST *lhs_aieast = dynamic_cast<ArrayIndexedExprAST*>(ast->LHS);
802 if (lhs_ast
== NULL
) {
803 throw CompilerException("Left hand side is not a variable (this is a limitation of the current system)", ast
->filepos
);
805 //boost::shared_ptr<TypeInfo> lhs_type = resolveType(ast->children[0]);
806 //std::cout << "Accessing type: " << lhs_type.get()->declType << std::endl;
809 ClassAST
* s
= this->classes
[ast
->children
[0]->programmaticType
.declType
];
810 //check to see if the struct has an attribute member named this
812 bool foundVar
= false;
813 for (std::vector
<ASTNode
*>::iterator iter
= s
->children
.begin(),
814 end
= s
->children
.end(); iter
!= end
; ++iter
) {
816 VarDeclExprAST
*vdeast
= dynamic_cast<VarDeclExprAST
*>(*iter
);
817 if (vdeast
!= NULL
) {
818 if (vdeast
->vi
->name
== veast
->name
) {
819 gc
.get()->output
<< lhs_ast
->name
<< "->" << veast
->name
;
825 if (foundVar
== false) {
826 std::ostringstream msg
;
827 msg
<< "Can't find '" << veast
->name
<< "' inside of '" << lhs_ast
->name
<< "'";
828 throw CompilerException(msg
.str(), ast
->filepos
);
832 gc_temp
= handleCall(ceast
, ast
->children
[0]->programmaticType
.declType
, lhs_ast
->name
);
833 if (gc_temp
.get()->decls
.str() != "") {
834 gc
.get()->decls
<< gc_temp
.get()->decls
.str();
836 if (gc_temp
.get()->inits
.str() != "") {
837 gc
.get()->output
<< gc_temp
.get()->inits
.str();
839 if (gc_temp
.get()->output
.str() != "") {
840 gc
.get()->output
<< gc_temp
.get()->output
.str();
846 gc_temp
= visit (ast
->children
[0]);
847 if (gc_temp
.get()->decls
.str() != "") {
848 gc
.get()->decls
<< gc_temp
.get()->decls
.str();
850 if (gc_temp
.get()->inits
.str() != "") {
851 gc
.get()->inits
<< gc_temp
.get()->inits
.str();
853 if (gc_temp
.get()->output
.str() != "") {
854 gc
.get()->output
<< gc_temp
.get()->output
.str();
856 gc
.get()->output
<< ast
->op
;
857 gc_temp
= visit (ast
->children
[1]);
858 if (gc_temp
.get()->decls
.str() != "") {
859 gc
.get()->decls
<< gc_temp
.get()->decls
.str();
861 if (gc_temp
.get()->inits
.str() != "") {
862 gc
.get()->inits
<< gc_temp
.get()->inits
.str();
864 if (gc_temp
.get()->output
.str() != "") {
865 gc
.get()->output
<< gc_temp
.get()->output
.str();
871 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::visit(CallExprAST
*ast
) {
872 return handleCall(ast
, "", "");
876 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::visit(ClassAST
*ast
, DeclStage::Stage stage
) {
877 boost::shared_ptr
<GeneratedCode
> gc(new GeneratedCode
), gc_temp(new GeneratedCode
);
880 VarDeclExprAST
*varDecl
;
882 //DeclStage::Stage stage;
883 if (stage
== DeclStage::FORWARD
) {
884 this->classes
[ast
->name
] = ast
;
885 gc
.get()->output
<< "class " << ast
->name
<< ";" << std::endl
;
887 if (stage
== DeclStage::IMPL
) {
888 std::map
<std::string
, ActorAST
*>::iterator finder
;
890 currentScopeCount
.push_back(0);
891 scopeContainerId
= currentScopeCount
.size(); //remember where we started
892 gc
.get()->output
<< "class " << ast
->name
<< " {" << std::endl
<< "public: " << std::endl
;
893 currentFunGroup
= funStack
.size();
895 //then push a variable that will be how we message ourselves
896 std::string
name("this");
897 VariableInfo
*vi
= new VariableInfo(name
, ast
->name
, ContainerType::Scalar
, ScopeType::Struct
);
898 ++(currentScopeCount
.back());
899 scopeStack
.push_back(vi
);
901 for (std::vector
<ASTNode
*>::iterator iter
= ast
->children
.begin(), end
= ast
->children
.end(); iter
!= end
; ++iter
) {
902 switch ((*iter
)->type()) {
903 case (NodeType::Function
) :
904 funStack
.push_back(dynamic_cast<PrototypeAST
*>((*iter
)->children
[0]));
906 case (NodeType::VarDecl
) :
907 varDecl
= dynamic_cast<VarDeclExprAST
*>(*iter
);
909 varDecl
->vi
->scopeType
= ScopeType::Struct
;
911 ++(currentScopeCount
.back());
912 scopeStack
.push_back(varDecl
->vi
);
915 throw CompilerException("Unknown feature insde of class", (*iter
)->filepos
);
920 for (std::vector
<ASTNode
*>::iterator iter
= ast
->children
.begin(), end
= ast
->children
.end(); iter
!= end
; ++iter
) {
921 switch ((*iter
)->type()) {
922 case (NodeType::Function
) :
923 funast
= dynamic_cast<FunctionAST
*>(*iter
);
924 gc_temp
= visit(funast
, stage
);
926 case (NodeType::VarDecl
) :
927 varDecl
= dynamic_cast<VarDeclExprAST
*>(*iter
);
929 finder
= actors
.find(varDecl
->vi
->type
.declType
);
931 if (finder
!= actors
.end()) {
932 if (varDecl
->vi
->type
.containerType
== ContainerType::Scalar
) {
933 gc
.get()->output
<< "actorId_t " << varDecl
->vi
->name
<< ";" << std::endl
;
935 else if (varDecl
->vi
->type
.containerType
== ContainerType::Array
) {
936 gc
.get()->output
<< "actorId_t " << varDecl
->vi
->name
<< "[";
938 boost::shared_ptr
<GeneratedCode
> gc_temp
= visit (varDecl
->vi
->size
);
939 if (gc_temp
.get()->decls
.str() != "") {
940 gc
.get()->output
<< gc_temp
.get()->decls
.str();
942 if (gc_temp
.get()->inits
.str() != "") {
943 gc
.get()->output
<< gc_temp
.get()->inits
.str();
945 if (gc_temp
.get()->output
.str() != "") {
946 gc
.get()->output
<< gc_temp
.get()->output
.str();
949 gc
.get()->output
<< "];" << std::endl
;
954 if (varDecl
->vi
->type
.containerType
== ContainerType::Scalar
) {
955 gc
.get()->output
<< lookupAssocType(varDecl
->vi
->type
) << " " << varDecl
->vi
->name
<< ";" << std::endl
;
957 else if (varDecl
->vi
->type
.containerType
== ContainerType::Array
) {
958 gc
.get()->output
<< lookupAssocType(varDecl
->vi
->type
) << " " << varDecl
->vi
->name
<< "[";
959 boost::shared_ptr
<GeneratedCode
> gc_temp
= visit (varDecl
->vi
->size
);
961 if (gc_temp
.get()->decls
.str() != "") {
962 gc
.get()->output
<< gc_temp
.get()->decls
.str();
964 if (gc_temp
.get()->inits
.str() != "") {
965 gc
.get()->output
<< gc_temp
.get()->inits
.str();
967 if (gc_temp
.get()->output
.str() != "") {
968 gc
.get()->output
<< gc_temp
.get()->output
.str();
971 gc
.get()->output
<< "];" << std::endl
;
977 throw CompilerException("Unknown feature insde of class", (*iter
)->filepos
);
980 if (gc_temp
.get()->decls
.str() != "") {
981 gc
.get()->output
<< gc_temp
.get()->decls
.str();
983 if (gc_temp
.get()->inits
.str() != "") {
984 gc
.get()->output
<< gc_temp
.get()->inits
.str();
986 if (gc_temp
.get()->output
.str() != "") {
987 gc
.get()->output
<< gc_temp
.get()->output
.str();
991 gc
.get()->output
<< ast
->name
<< "() { }" << std::endl
;
993 //TODO: I'm not sure if I need a traditional copy constructor, or this pointer style
994 //gc.get()->output << ast->name << "(const " << ast->name << "& p) {" << std::endl;
995 gc
.get()->output
<< ast
->name
<< "(" << ast
->name
<< "* p__) {" << std::endl
;
997 for (std::vector
<ASTNode
*>::iterator iter
= ast
->children
.begin(), end
= ast
->children
.end(); iter
!= end
; ++iter
) {
998 VarDeclExprAST
*vdeast
= dynamic_cast<VarDeclExprAST
*>(*iter
);
999 if (vdeast
!= NULL
) {
1000 if (vdeast
->vi
->type
.requiresCopyDelete()) {
1001 gc
.get()->output
<< "if (" << vdeast
->vi
->name
1002 << " != NULL) { delete " << vdeast
->vi
->name
<< "; };" << std::endl
;
1003 gc
.get()->output
<< vdeast
->vi
->name
<< " = new "
1004 << lookupAssocType(vdeast
->vi
->type
) << "(p__->" << vdeast
->vi
->name
<< ");" << std::endl
;
1007 gc
.get()->output
<< vdeast
->vi
->name
<< " = " << "p__->" << vdeast
->vi
->name
<< ";" << std::endl
;
1011 gc
.get()->output
<< "}" << std::endl
;
1012 gc
.get()->output
<< "};" << std::endl
;
1014 int unwindAmount
= currentScopeCount
.back();
1015 for (int i
= 0; i
< unwindAmount
; ++i
) {
1016 scopeStack
.pop_back();
1018 currentScopeCount
.pop_back();
1020 //Get us back to seeing only the functions we could see before we entered the actor
1021 while (funStack
.size() != currentFunGroup
) {
1022 funStack
.pop_back();
1028 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::visit(ActorAST
*ast
, DeclStage::Stage stage
) {
1029 boost::shared_ptr
<GeneratedCode
> gc(new GeneratedCode
), gc_temp(new GeneratedCode
);
1032 FunctionAST
*funast
;
1033 VarDeclExprAST
*varDecl
;
1035 //DeclStage::Stage stage;
1036 if (stage
== DeclStage::DECL
) {
1037 currentScopeCount
.push_back(0);
1038 scopeContainerId
= currentScopeCount
.size(); //remember where we started
1039 gc
.get()->output
<< "class " << ast
->name
<< " : public Actor {" << std::endl
<< "public: " << std::endl
;
1040 currentFunGroup
= funStack
.size();
1042 //then push a variable that will be how we message ourselves
1043 std::string
name("this");
1044 VariableInfo
*vi
= new VariableInfo(name
, ast
->name
, ContainerType::Scalar
, ScopeType::Actor
);
1045 ++(currentScopeCount
.back());
1046 scopeStack
.push_back(vi
);
1048 actors
[ast
->name
] = ast
;
1050 for (std::vector
<ASTNode
*>::iterator iter
= ast
->children
.begin(), end
= ast
->children
.end(); iter
!= end
; ++iter
) {
1051 switch ((*iter
)->type()) {
1052 case (NodeType::Function
) :
1053 if (stage
== DeclStage::DECL
) {
1054 funStack
.push_back(dynamic_cast<PrototypeAST
*>((*iter
)->children
[0]));
1056 funast
= dynamic_cast<FunctionAST
*>(*iter
);
1057 gc_temp
= visit(funast
, stage
);
1059 case (NodeType::VarDecl
) :
1060 varDecl
= dynamic_cast<VarDeclExprAST
*>(*iter
);
1061 if (stage
== DeclStage::DECL
) {
1062 varDecl
->vi
->scopeType
= ScopeType::Actor
;
1064 ++(currentScopeCount
.back());
1065 scopeStack
.push_back(varDecl
->vi
);
1066 std::map
<std::string
, ActorAST
*>::iterator finder
= actors
.find(varDecl
->vi
->type
.declType
);
1068 if (finder
!= actors
.end()) {
1069 if (varDecl
->vi
->type
.containerType
== ContainerType::Scalar
) {
1070 gc
.get()->output
<< "actorId_t " << varDecl
->vi
->name
<< ";" << std::endl
;
1072 else if (varDecl
->vi
->type
.containerType
== ContainerType::Array
) {
1073 gc
.get()->output
<< "actorId_t " << varDecl
->vi
->name
<< "[";
1075 boost::shared_ptr
<GeneratedCode
> gc_temp
= visit (varDecl
->vi
->size
);
1076 if (gc_temp
.get()->decls
.str() != "") {
1077 gc
.get()->output
<< gc_temp
.get()->decls
.str();
1079 if (gc_temp
.get()->inits
.str() != "") {
1080 gc
.get()->output
<< gc_temp
.get()->inits
.str();
1082 if (gc_temp
.get()->output
.str() != "") {
1083 gc
.get()->output
<< gc_temp
.get()->output
.str();
1086 gc
.get()->output
<< "];" << std::endl
;
1091 if (varDecl
->vi
->type
.containerType
== ContainerType::Scalar
) {
1092 gc
.get()->output
<< lookupAssocType(varDecl
->vi
->type
) << " " << varDecl
->vi
->name
<< ";" << std::endl
;
1094 else if (varDecl
->vi
->type
.containerType
== ContainerType::Array
) {
1095 gc
.get()->output
<< lookupAssocType(varDecl
->vi
->type
) << " " << varDecl
->vi
->name
<< "[";
1096 boost::shared_ptr
<GeneratedCode
> gc_temp
= visit (varDecl
->vi
->size
);
1098 if (gc_temp
.get()->decls
.str() != "") {
1099 gc
.get()->output
<< gc_temp
.get()->decls
.str();
1101 if (gc_temp
.get()->inits
.str() != "") {
1102 gc
.get()->output
<< gc_temp
.get()->inits
.str();
1104 if (gc_temp
.get()->output
.str() != "") {
1105 gc
.get()->output
<< gc_temp
.get()->output
.str();
1108 gc
.get()->output
<< "];" << std::endl
;
1115 case (NodeType::Action
) :
1119 throw CompilerException("Unhandled element in actor definition", (*iter
)->filepos
);
1122 if (gc_temp
.get()->decls
.str() != "") {
1123 gc
.get()->output
<< gc_temp
.get()->decls
.str();
1125 if (gc_temp
.get()->inits
.str() != "") {
1126 gc
.get()->output
<< gc_temp
.get()->inits
.str();
1128 if (gc_temp
.get()->output
.str() != "") {
1129 gc
.get()->output
<< gc_temp
.get()->output
.str();
1133 if (stage
== DeclStage::DECL
) {
1134 gc
.get()->output
<< "};" << std::endl
;
1137 for (std::vector
<ASTNode
*>::iterator iter
= ast
->children
.begin(), end
= ast
->children
.end(); iter
!= end
; ++iter
) {
1138 switch ((*iter
)->type()) {
1139 case (NodeType::Action
) :
1140 actast
= dynamic_cast<ActionAST
*>(*iter
);
1141 gc_temp
= visit(actast
, ast
->name
, stage
);
1143 if (gc_temp
.get()->decls
.str() != "") {
1144 gc
.get()->output
<< gc_temp
.get()->decls
.str();
1146 if (gc_temp
.get()->inits
.str() != "") {
1147 gc
.get()->output
<< gc_temp
.get()->inits
.str();
1149 if (gc_temp
.get()->output
.str() != "") {
1150 gc
.get()->output
<< gc_temp
.get()->output
.str();
1153 case (NodeType::Function
) :
1156 case (NodeType::VarDecl
) :
1160 throw CompilerException("Unhandled element in actor definition", (*iter
)->filepos
);
1165 if (stage
== DeclStage::IMPL
) {
1166 int unwindAmount
= currentScopeCount
.back();
1167 for (int i
= 0; i
< unwindAmount
; ++i
) {
1168 scopeStack
.pop_back();
1170 currentScopeCount
.pop_back();
1172 //Get us back to seeing only the functions we could see before we entered the actor
1173 while (funStack
.size() != currentFunGroup
) {
1174 funStack
.pop_back();
1180 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::visit(PrototypeAST
*ast
, DeclStage::Stage stage
) {
1181 boost::shared_ptr
<GeneratedCode
> gc(new GeneratedCode
);
1183 bool isExtern
= checkIfExtern(ast
->name
);
1185 gc
.get()->output
<< lookupAssocType(ast
->returnType
) << " " << ast
->name
<< "(";
1186 for (int i
= 0, j
= ast
->children
.size(); i
!= j
; ++i
) {
1187 VarDeclExprAST
*varDecl
= dynamic_cast<VarDeclExprAST
*>(ast
->children
[i
]);
1188 if (stage
== DeclStage::IMPL
) {
1189 ++(currentScopeCount
.back());
1190 scopeStack
.push_back(varDecl
->vi
);
1193 gc
.get()->output
<< ", ";
1196 gc
.get()->output
<< lookupAssocType(varDecl
->vi
->type
) << " " << varDecl
->vi
->name
;
1199 if (ast
->children
.size() > 0) {
1200 gc
.get()->output
<< ", ";
1202 gc
.get()->output
<< "Actor *actor__";
1204 gc
.get()->output
<< ")";
1208 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::visit(FunctionAST
*ast
, DeclStage::Stage stage
) {
1209 boost::shared_ptr
<GeneratedCode
> gc(new GeneratedCode
);
1211 PrototypeAST
*proto
= dynamic_cast<PrototypeAST
*>(ast
->children
[0]);
1213 if (stage
== DeclStage::FORWARD
) {
1214 if (ast
->children
[1]->children
.size() == 0) {
1215 gc
.get()->output
<< "extern ";
1216 //this->externFns.push_back(ast->proto->name);
1218 boost::shared_ptr
<GeneratedCode
> gc_temp
= visit (proto
, stage
);
1219 if (gc_temp
.get()->decls
.str() != "") {
1220 gc
.get()->decls
<< gc_temp
.get()->decls
.str();
1222 if (gc_temp
.get()->inits
.str() != "") {
1223 gc
.get()->output
<< gc_temp
.get()->inits
.str();
1225 if (gc_temp
.get()->output
.str() != "") {
1226 gc
.get()->output
<< gc_temp
.get()->output
.str();
1229 gc
.get()->output
<< ";" << std::endl
;
1231 else if (stage
== DeclStage::IMPL
) {
1232 if (ast
->children
[1]->children
.size() == 0) {
1233 boost::shared_ptr
<GeneratedCode
> gc_temp(new GeneratedCode
);
1237 scopeContainerId
= currentScopeCount
.size(); //remember where we started
1238 currentScopeCount
.push_back(0);
1240 boost::shared_ptr
<GeneratedCode
> gc_temp
= visit (proto
, stage
);
1241 if (gc_temp
.get()->decls
.str() != "") {
1242 gc
.get()->decls
<< gc_temp
.get()->decls
.str();
1244 if (gc_temp
.get()->inits
.str() != "") {
1245 gc
.get()->decls
<< gc_temp
.get()->inits
.str();
1247 if (gc_temp
.get()->output
.str() != "") {
1248 gc
.get()->decls
<< gc_temp
.get()->output
.str();
1251 setupDontCare(proto
->returnType
);
1255 gc
.get()->decls
<< "{" << std::endl
;
1257 gc
.get()->output
<< "TypeUnion tmpTU__;" << std::endl
;
1258 gc
.get()->output
<< "unsigned int timeLeft__ = actor__->parentThread->timeSliceEndTime;" << std::endl
;
1260 gc
.get()->output
<< "actor__->parentThread->timeSliceEndTime = timeLeft__;" << std::endl
;
1261 gc
.get()->output
<< "int contId__ = 0;" << std::endl
;
1262 gc
.get()->output
<< "if (actor__->isResuming) {" << std::endl
;
1263 gc
.get()->output
<< " contId__ = actor__->heapStack.back().Int32; actor__->heapStack.pop_back();" << std::endl
;
1264 gc
.get()->output
<< " if (actor__->heapStack.size() == 0) {" << std::endl
;
1265 gc
.get()->output
<< " actor__->isResuming = false;" << std::endl
;
1266 gc
.get()->output
<< " }" << std::endl
;
1267 gc
.get()->output
<< "}" << std::endl
;
1268 gc
.get()->output
<< "actor__->parentThread->timeSliceEndTime = timeLeft__;" << std::endl
;
1270 gc
.get()->output
<< "switch(contId__) {" <<std::endl
;
1271 gc
.get()->output
<< "case(" << currentContId
<< "):" << std::endl
;
1275 for (std::vector
<ASTNode
*>::iterator iter
= ast
->children
[1]->children
.begin(),
1276 end
= ast
->children
[1]->children
.end(); iter
!= end
; ++iter
) {
1277 boost::shared_ptr
<GeneratedCode
> gc_temp
= visit (*iter
);
1278 if (gc_temp
.get()->decls
.str() != "") {
1279 gc
.get()->decls
<< gc_temp
.get()->decls
.str();
1281 if (gc_temp
.get()->inits
.str() != "") {
1282 gc
.get()->output
<< gc_temp
.get()->inits
.str();
1284 if (gc_temp
.get()->output
.str() != "") {
1285 gc
.get()->output
<< gc_temp
.get()->output
.str();
1287 gc
.get()->output
<< ";" << std::endl
;
1291 gc
.get()->output
<< " }" << std::endl
;
1293 int unwindAmount
= currentScopeCount
.back();
1294 for (int i
= 0; i
< unwindAmount
; ++i
) {
1295 VariableInfo
*vi
= scopeStack
.back();
1296 if (vi
->type
.containerType
== ContainerType::Array
) {
1297 gc
.get()->output
<< "if (" << vi
->name
<< " != NULL) {" << std::endl
;
1298 if (isCopyDelete(vi
->type
)) {
1299 gc
.get()->output
<< " for (int i__=0; i__ < " << vi
->name
<< "->size(); ++i__) { if (" << vi
->name
<< "[i__] != NULL) { delete " << vi
->name
<< "[i__];} }" << std::endl
;
1301 gc
.get()->output
<< " " << vi
->name
<< "->clear();" << std::endl
;
1302 gc
.get()->output
<< " delete(" << vi
->name
<< ");" << std::endl
;
1303 gc
.get()->output
<< "}" << std::endl
;
1305 else if ((vi
->type
.requiresCopyDelete())&&(!checkIfActor(vi
->type
.declType
))) {
1306 gc
.get()->output
<< "if (" << vi
->name
<< " != NULL) {" << std::endl
;
1307 gc
.get()->output
<< " delete(" << vi
->name
<< ");" << std::endl
;
1308 gc
.get()->output
<< "}" << std::endl
;
1310 scopeStack
.pop_back();
1312 currentScopeCount
.pop_back();
1314 gc
.get()->output
<< "}" << std::endl
;
1321 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::visit(ActionAST
*ast
, std::string actorName
, DeclStage::Stage stage
) {
1322 boost::shared_ptr
<GeneratedCode
> gc(new GeneratedCode
);
1325 PrototypeAST
*proto
= dynamic_cast<PrototypeAST
*>(ast
->children
[0]);
1327 if (stage
== DeclStage::DECL
) {
1328 gc
.get()->output
<< "void " << actorName
<< "__" << proto
->name
<< "_action(Actor *a__);" << std::endl
;
1330 else if (stage
== DeclStage::IMPL
) {
1331 gc
.get()->decls
<< "void " << actorName
<< "__" << proto
->name
<< "_action(Actor *a__) ";
1333 scopeContainerId
= currentScopeCount
.size(); //remember where we started
1334 currentScopeCount
.push_back(0);
1337 //std::string retVal = "void";
1338 //setupDontCare(retVal);
1339 this->dontCareReturnVal
= "";
1341 gc
.get()->decls
<< "{" << std::endl
;
1343 gc
.get()->decls
<< actorName
<< " *actor__ = static_cast<" << actorName
<< "*>(a__);" << std::endl
;
1344 gc
.get()->decls
<< "TypeUnion tmpTU__;" << std::endl
;
1345 gc
.get()->decls
<< "unsigned int timeLeft__ = actor__->parentThread->timeSliceEndTime;" << std::endl
;
1347 gc
.get()->output
<< "int contId__ = 0;" << std::endl
;
1348 gc
.get()->output
<< "if (actor__->isResuming) {" << std::endl
;
1349 gc
.get()->output
<< " contId__ = actor__->heapStack.back().Int32; actor__->heapStack.pop_back();" << std::endl
;
1350 gc
.get()->output
<< " if (actor__->heapStack.size() == 0) {" << std::endl
;
1351 gc
.get()->output
<< " actor__->isResuming = false;" << std::endl
;
1352 gc
.get()->output
<< " }" << std::endl
;
1353 gc
.get()->output
<< "}" << std::endl
;
1354 gc
.get()->output
<< "else {" << std::endl
;
1356 for (std::vector
<ASTNode
*>::reverse_iterator iter
= ast
->children
[0]->children
.rbegin(), end
= ast
->children
[0]->children
.rend(); iter
!= end
; ++iter
) {
1357 VarDeclExprAST
*varDecl
= dynamic_cast<VarDeclExprAST
*>(*iter
);
1358 gc
.get()->decls
<< lookupAssocType(varDecl
->vi
->type
) << " " << varDecl
->vi
->name
<< ";" << std::endl
;
1359 gc
.get()->output
<< lookupPopForVar(varDecl
->vi
) << ";" << std::endl
;
1361 ++(currentScopeCount
.back());
1362 scopeStack
.push_back(varDecl
->vi
);
1364 gc
.get()->output
<< "}" << std::endl
;
1366 gc
.get()->output
<< "switch(contId__) {" <<std::endl
;
1367 gc
.get()->output
<< "case(" << currentContId
<< "):" << std::endl
;
1370 for (std::vector
<ASTNode
*>::iterator iter
= ast
->children
[1]->children
.begin(),
1371 end
= ast
->children
[1]->children
.end(); iter
!= end
; ++iter
) {
1372 boost::shared_ptr
<GeneratedCode
> gc_temp
= visit (*iter
);
1373 if (gc_temp
.get()->decls
.str() != "") {
1374 gc
.get()->decls
<< gc_temp
.get()->decls
.str();
1376 if (gc_temp
.get()->inits
.str() != "") {
1377 gc
.get()->output
<< gc_temp
.get()->inits
.str();
1379 if (gc_temp
.get()->output
.str() != "") {
1380 gc
.get()->output
<< gc_temp
.get()->output
.str();
1383 gc
.get()->output
<< ";" << std::endl
;
1386 gc
.get()->output
<< "}" << std::endl
;
1387 gc
.get()->output
<< "--timeLeft__;" << std::endl
;
1388 gc
.get()->output
<< "actor__->parentThread->timeSliceEndTime = timeLeft__;" << std::endl
;
1389 gc
.get()->output
<< "actor__->actorState = ActorState::WAITING_FOR_ACTION;" << std::endl
;
1391 int unwindAmount
= currentScopeCount
.back();
1392 for (int i
= 0; i
< unwindAmount
; ++i
) {
1393 VariableInfo
*vi
= scopeStack
.back();
1394 if ((vi
->type
.requiresCopyDelete())&&(!checkIfActor(vi
->type
.declType
))) {
1395 gc
.get()->output
<< "if (" << vi
->name
<< " != NULL) {" << std::endl
;
1396 gc
.get()->output
<< " delete(" << vi
->name
<< ");" << std::endl
;
1397 gc
.get()->output
<< "}" << std::endl
;
1399 scopeStack
.pop_back();
1401 currentScopeCount
.pop_back();
1403 gc
.get()->output
<< "}" << std::endl
;
1409 boost::shared_ptr
<GeneratedCode
> CodegenCPPOutput::visit(AppAST
*ast
) {
1410 boost::shared_ptr
<GeneratedCode
> gc(new GeneratedCode
), gc_temp(new GeneratedCode
);
1413 FunctionAST
*funast
;
1417 ActionAST
*mainAction
= NULL
;
1419 gc
.get()->decls
<< "//automatically generated by Minnow->C++ codegen (0.1)" << std::endl
;
1420 gc
.get()->decls
<< "#include \"aquarium.hpp\"" << std::endl
;
1422 gc
.get()->decls
<< "inline int convertToInt(std::string s){std::istringstream i(s);int x;i >> x;return x;}" << std::endl
;
1423 gc
.get()->decls
<< "inline void puti(int i){std::cout << i << std::endl; }" << std::endl
;
1424 gc
.get()->decls
<< "inline void putstring(std::string s){std::cout << s << std::endl; }" << std::endl
;
1426 DeclStage::Stage stage
;
1427 for (int i
= 0; i
< 3; ++i
) {
1429 case (0) : stage
= DeclStage::FORWARD
; break;
1430 case (1) : stage
= DeclStage::DECL
; break;
1431 case (2) : stage
= DeclStage::IMPL
; break;
1433 for (std::vector
<ASTNode
*>::iterator iter
= ast
->children
.begin(), end
= ast
->children
.end(); iter
!= end
; ++iter
) {
1434 //std::cout << "CHILD: " << (*iter)->nodeType << " at " << (*iter)->filepos.lineNumber << " " << (*iter)->filepos.colStart << std::endl;
1435 switch ((*iter
)->type()) {
1436 case (NodeType::Action
) :
1437 actast
= dynamic_cast<ActionAST
*>(*iter
);
1438 if (stage
== DeclStage::FORWARD
) {
1439 if (dynamic_cast<PrototypeAST
*>(actast
->children
[0])->name
!= "main") {
1440 throw CompilerException("Only the 'main' action is allowed at the top level");
1443 mainAction
= actast
;
1446 gc_temp
= visit(actast
, "Actor", stage
);
1448 case (NodeType::Function
) :
1449 if (stage
== DeclStage::FORWARD
) {
1450 funStack
.push_back(dynamic_cast<PrototypeAST
*>((*iter
)->children
[0]));
1452 funast
= dynamic_cast<FunctionAST
*>(*iter
);
1453 gc_temp
= visit(funast
, stage
);
1455 case (NodeType::Actor
) :
1456 actorast
= dynamic_cast<ActorAST
*>(*iter
);
1457 gc_temp
= visit(actorast
, stage
);
1459 case (NodeType::Class
) :
1460 classast
= dynamic_cast<ClassAST
*>(*iter
);
1461 gc_temp
= visit(classast
, stage
);
1464 throw CompilerException("Unhandled element in application", (*iter
)->filepos
);
1467 if (gc_temp
.get()->decls
.str() != "") {
1468 gc
.get()->output
<< gc_temp
.get()->decls
.str();
1470 if (gc_temp
.get()->inits
.str() != "") {
1471 gc
.get()->output
<< gc_temp
.get()->inits
.str();
1473 if (gc_temp
.get()->output
.str() != "") {
1474 gc
.get()->output
<< gc_temp
.get()->output
.str();
1480 gc
.get()->output
<< "int main(int argc, char *argv[]){" << std::endl
;
1482 if (mainAction
== NULL
) {
1483 throw CompilerException("Can not find 'main' action");
1486 PrototypeAST
* mainProto
= dynamic_cast<PrototypeAST
*>(mainAction
->children
[0]);
1488 if (mainProto
->children
.size() > 0) {
1489 gc
.get()->output
<< "VM_Main(argc, argv, Actor__main_action, true);" << std::endl
;
1492 gc
.get()->output
<< "VM_Main(argc, argv, Actor__main_action, false);" << std::endl
;
1497 gc
.get()->output
<< "return(0);" << std::endl
;
1498 gc
.get()->output
<< "};" << std::endl
;
1502 std::string
CodegenCPPOutput::translate(ASTNode
*ast
) {
1503 boost::shared_ptr
<GeneratedCode
> gc(new GeneratedCode
);
1507 std::ostringstream output
;
1508 if (gc
.get()->decls
.str() != "") {
1509 output
<< gc
.get()->decls
.str();
1511 if (gc
.get()->inits
.str() != "") {
1512 output
<< gc
.get()->inits
.str();
1514 if (gc
.get()->output
.str() != "") {
1515 output
<< gc
.get()->output
.str();
1518 return output
.str();