00001 #include "typecheckervisitor.h"
00002 #include "protomake.h"
00003 #include <typeinfo>
00004 #include <string>
00005 #include <iostream>
00006
00007 using namespace std;
00008
00009 VisitorReturn *TypeCheckerVisitor::visitAction(Action *action) {
00010 VisitorReturn *v= new VisitorReturn;
00011 return v;
00012 }
00013
00014 VisitorReturn *TypeCheckerVisitor::visitActStatement(ActStatement *actStatement) {
00015 VisitorReturn *v= new VisitorReturn;
00016 Type *t = new Type(actStatement->getIdentifier()->getPosition(), Type::TIMEOUT);
00017 string str = actStatement->getIdentifier()->getName();
00018
00019 map<string, Type*>::iterator i = this->symbolTable.find("@" + str);
00020 if(i != this->symbolTable.end()) {
00021 t = this->symbolTable["@" + str];
00022 this->symbolTable.erase("@" + str);
00023 }
00024
00025 this->stack.push_back(t);
00026 this->insert = true;
00027 v = actStatement->getIdentifier()->visit(*this);
00028 this->insert = false;
00029 this->stack.pop_back();
00030
00031 v = actStatement->getExpression()->visit(*this);
00032 if(v->type->getTypeCode() != Type::INTEGER) {
00033 cerr << "Expression não é INTEGER\n";
00034 exit(1);
00035 }
00036
00037 return v;
00038 }
00039
00040 VisitorReturn *TypeCheckerVisitor::visitArrayReference(ArrayReference *arrayReference) {
00041 VisitorReturn *v= new VisitorReturn;
00042 return v;
00043 }
00044
00045 VisitorReturn *TypeCheckerVisitor::visitArrayType(ArrayType *arrayType) {
00046 VisitorReturn *v= new VisitorReturn;
00047 return v;
00048 }
00049
00050 VisitorReturn *TypeCheckerVisitor::visitAssignStatement(AssignStatement *assignStatement) {
00051 VisitorReturn *v1, *v2;
00052
00053 v1 = assignStatement->getLeftSideList()->visit(*this);
00054 v2 = assignStatement->getExpressionList()->visit(*this);
00055
00056 if(v1->type->getTypeCode() != v2->type->getTypeCode()) {
00057 cerr << "Tipos de expressoes não são iguais\n";
00058 exit(1);
00059 }
00060
00061 return v1;
00062 }
00063
00064 VisitorReturn *TypeCheckerVisitor::visitAst(Ast *ast) {
00065 VisitorReturn *v= new VisitorReturn;
00066 return v;
00067 }
00068
00069 VisitorReturn *TypeCheckerVisitor::visitBehavior(Behavior *behavior) {
00070 VisitorReturn *v= new VisitorReturn;
00071 return v;
00072 }
00073
00074 VisitorReturn *TypeCheckerVisitor::visitBehaviorStatement(BehaviorStatement *behaviorStatement) {
00075 VisitorReturn *v= new VisitorReturn;
00076
00077 v = behaviorStatement->getBehavior()->visit(*this);
00078 if(v->type->getTypeCode() != Type::BEHAVIOR) {
00079 cerr << "Behavior não é BEHAVIOR\n";
00080 exit(1);
00081 }
00082
00083 behaviorStatement->getExpressionList()->visit(*this);
00084
00085 return v;
00086 }
00087
00088 VisitorReturn *TypeCheckerVisitor::visitBinaryExpression(BinaryExpression *binaryExpression) {
00089 VisitorReturn *v1, *v2;
00090 string op;
00091 Type *type;
00092
00093 v1 = binaryExpression->getLeftExpression()->visit(*this);
00094 v2 = binaryExpression->getRightExpression()->visit(*this);
00095 op = binaryExpression->getOp();
00096
00097 if(v1->type->getTypeCode() != v2->type->getTypeCode()) {
00098 cerr << "Tipos de expressões binárias não são iguais\n";
00099 exit(1);
00100 }
00101
00102 if((op == "&") || (op == "|")) {
00103 type = new Type(binaryExpression->getPosition(),Type::BOOLEAN);
00104 if(v1->type->getTypeCode() != Type::BOOLEAN) {
00105 cerr << "Operadores booleanos aplicados a expressões não booleanas\n";
00106 exit(1);
00107 }
00108 } else {
00109 if((op == "+") || (op == "-") || (op == "*") || (op == "/")) {
00110 type = new Type(binaryExpression->getPosition(),Type::INTEGER);
00111 } else {
00112 type = new Type(binaryExpression->getPosition(),Type::BOOLEAN);
00113 }
00114 if((v1->type->getTypeCode() != Type::INTEGER) && (op != "=")) {
00115 cerr << "Operadores aritmeticos aplicados a expressões não inteiras\n";
00116 exit(1);
00117 }
00118 }
00119
00120 v1->type = type;
00121
00122 return v1;
00123 }
00124
00125 VisitorReturn *TypeCheckerVisitor::visitDeclaration(Declaration *declaration) {
00126 VisitorReturn *v= new VisitorReturn;
00127 return v;
00128 }
00129
00130 VisitorReturn *TypeCheckerVisitor::visitDoStatement(DoStatement *doStatement) {
00131 VisitorReturn *v= new VisitorReturn;
00132
00133 v = doStatement->getGuardedStatement()->visit(*this);
00134
00135 return v;
00136 }
00137
00138 VisitorReturn *TypeCheckerVisitor::visitExpression(Expression *expression) {
00139 VisitorReturn *v= new VisitorReturn;
00140 return v;
00141 }
00142
00143 VisitorReturn *TypeCheckerVisitor::visitExpressionList(ExpressionList *expressionList) {
00144 VisitorReturn *v= new VisitorReturn;
00145 return v;
00146 }
00147
00148 VisitorReturn *TypeCheckerVisitor::visitFieldDeclaration(FieldDeclaration *fieldDeclaration) {
00149 VisitorReturn *v= new VisitorReturn;
00150 return v;
00151 }
00152
00153 VisitorReturn *TypeCheckerVisitor::visitFieldReference(FieldReference *fieldReference) {
00154 VisitorReturn *v= new VisitorReturn;
00155 string id;
00156
00157 id = fieldReference->getMsgId()->getName() + "." + fieldReference->getFieldId()->getName();
00158 map<string, Type*>::iterator i = this->symbolTable.find(id);
00159 if(i == this->symbolTable.end()) {
00160 cerr << "FieldReference não existe\n";
00161 exit(1);
00162 }
00163
00164 v->type = this->symbolTable[id];
00165
00166 return v;
00167 }
00168
00169 VisitorReturn *TypeCheckerVisitor::visitFieldType(FieldType *fieldType) {
00170 VisitorReturn *v= new VisitorReturn;
00171 SimpleMessage *sm;
00172 Identifier *id;
00173 string str;
00174 bool ehInteger = true;
00175 IntegerLiteral *il = 0;
00176
00177 if(typeid(*fieldType->getExpression()) == typeid(Identifier)) {
00178 ehInteger = false;
00179 sm = (SimpleMessage *)this->stack[this->stack.size()-1];
00180 id = (Identifier *)fieldType->getExpression();
00181 str = sm->getIdentifier()->getName() + "." + id->getName();
00182
00183 map<string, Type*>::iterator i = this->symbolTable.find(str);
00184 if(i == this->symbolTable.end()) {
00185 cerr << "FieldReference não existe\n";
00186 exit(1);
00187 }
00188 Type *t = (Type *)this->symbolTable[str];
00189 if(t->getTypeCode()==Type::STRING) {
00190 cerr << "Quantificador invalido, tipo bit requerido\n";
00191 exit(1);
00192 }
00193
00194 } else if(typeid(*fieldType->getExpression()) != typeid(IntegerLiteral)) {
00195 cerr << "Quantificador invalido, constante ou nome de campo requerido\n";
00196 exit(1);
00197 } else {
00198 il = (IntegerLiteral *)fieldType->getExpression();
00199 }
00200
00201 if(fieldType->getType() == FieldType::BIT && !ehInteger) {
00202 cerr << "Se for bit só pode ser constante\n";
00203 exit(1);
00204 } else if(ehInteger && (il->getValue() > 32) && (fieldType->getType() == FieldType::BIT)) {
00205 cerr << "So pode ter no maximo 32 bits\n";
00206 exit(1);
00207 }
00208
00209 Type *type = new Type(fieldType->getPosition(), fieldType->getType() == FieldType::BIT ? Type::INTEGER : Type::STRING);
00210 v->type = type;
00211 return v;
00212 }
00213
00214 VisitorReturn *TypeCheckerVisitor::visitGuard(Guard *guard) {
00215 VisitorReturn *v= new VisitorReturn;
00216 return v;
00217 }
00218
00219 VisitorReturn *TypeCheckerVisitor::visitGuardedStatement(GuardedStatement *guardedStatement) {
00220 VisitorReturn *v= new VisitorReturn;
00221 return v;
00222 }
00223
00224 VisitorReturn *TypeCheckerVisitor::visitGuardExpression(GuardExpression *guardExpression) {
00225 VisitorReturn *v= new VisitorReturn;
00226
00227 v = guardExpression->getExpression()->visit(*this);
00228 if(v->type->getTypeCode() != Type::BOOLEAN) {
00229 cerr << "A guarda tem que ser booleana\n";
00230 exit(1);
00231 }
00232 return v;
00233 }
00234
00235 VisitorReturn *TypeCheckerVisitor::visitGuardReceive(GuardReceive *guardReceive) {
00236 VisitorReturn *v= new VisitorReturn;
00237 guardReceive->getReceiveStatement()->visit(*this);
00238 return v;
00239 }
00240
00241 VisitorReturn *TypeCheckerVisitor::visitGuardTimeout(GuardTimeout *guardTimeout) {
00242 VisitorReturn *v= new VisitorReturn;
00243
00244 this->forgetIt = true;
00245 v = guardTimeout->getIdentifier()->visit(*this);
00246 this->forgetIt = false;
00247
00248 if(v->type->getTypeCode() != Type::TIMEOUT) {
00249 cerr << "O identifier tem que ser um timeout\n";
00250 exit(1);
00251 }
00252
00253 return v;
00254 }
00255
00256 VisitorReturn *TypeCheckerVisitor::visitIdentifier(Identifier *identifier) {
00257 VisitorReturn *v = new VisitorReturn;
00258 Type *t = 0;
00259
00260 if(this->insert) {
00261 t = (Type *)this->stack[this->stack.size()-1];
00262 map<string, Type*>::iterator i = this->symbolTable.find(identifier->getName());
00263 if(i != this->symbolTable.end()) {
00264 cerr << "identifier jah declarado\n";
00265 exit(1);
00266 }
00267 this->symbolTable[identifier->getName()] = t;
00268 v->type = t;
00269 } else {
00270 string str = identifier->getName();
00271 map<string, Type*>::iterator i = this->symbolTable.find(str);
00272 if(i == this->symbolTable.end()) {
00273 if(!this->forgetIt) {
00274 cerr << "identifier nao declarado\n";
00275 exit(1);
00276 } else {
00277 str = "@" + str;
00278 this->symbolTable[str] = new Type(identifier->getPosition(), Type::TIMEOUT);
00279 }
00280 }
00281 t = this->symbolTable[str];
00282 v->type = t;
00283 }
00284 return v;
00285 }
00286
00287 VisitorReturn *TypeCheckerVisitor::visitIdentifierList(IdentifierList *identifierList) {
00288 VisitorReturn *v= new VisitorReturn;
00289 return v;
00290 }
00291
00292 VisitorReturn *TypeCheckerVisitor::visitIfStatement(IfStatement *ifStatement) {
00293 VisitorReturn *v= new VisitorReturn;
00294 ifStatement->getGuardedStatement()->visit(*this);
00295 return v;
00296 }
00297
00298 VisitorReturn *TypeCheckerVisitor::visitImport(Import *import) {
00299 VisitorReturn *v= new VisitorReturn;
00300 return v;
00301 }
00302
00303 VisitorReturn *TypeCheckerVisitor::visitLeftSide(LeftSide *leftSide) {
00304 VisitorReturn *v= new VisitorReturn;
00305 return v;
00306 }
00307
00308 VisitorReturn *TypeCheckerVisitor::visitLeftSideList(LeftSideList *leftSideList) {
00309 VisitorReturn *v= new VisitorReturn;
00310 return v;
00311 }
00312
00313 VisitorReturn *TypeCheckerVisitor::visitMessage(Message *message) {
00314 VisitorReturn *v= new VisitorReturn;
00315 return v;
00316 }
00317
00318 VisitorReturn *TypeCheckerVisitor::visitMultipleArrayReference(MultipleArrayReference *multipleArrayReference) {
00319 VisitorReturn *v= new VisitorReturn;
00320 v = multipleArrayReference->getArrayReference()->visit(*this);
00321 if(v->type->getTypeCode() != Type::ARRAY) {
00322 cerr << "A referencia do array deve ser um ARRAY\n";
00323 exit(1);
00324 }
00325 v = multipleArrayReference->getExpression()->visit(*this);
00326 if(v->type->getTypeCode() != Type::INTEGER) {
00327 cerr << "A expression do array deve ser um INTEGER\n";
00328 exit(1);
00329 }
00330 Type *type = new Type(multipleArrayReference->getPosition(), Type::ARRAY);
00331 v->type = type;
00332 return v;
00333 }
00334
00335 VisitorReturn *TypeCheckerVisitor::visitProcess(Process *process) {
00336 VisitorReturn *v= new VisitorReturn;
00337 return v;
00338 }
00339
00340 VisitorReturn *TypeCheckerVisitor::visitProgram(Program *program) {
00341 VisitorReturn *v= new VisitorReturn;
00342 if(program->getImport())
00343 program->getImport()->visit(*this);
00344 if(program->getBehavior())
00345 program->getBehavior()->visit(*this);
00346
00347 program->getMessage()->visit(*this);
00348 program->getProcess()->visit(*this);
00349
00350
00351 map<string, Type*>::iterator i = this->symbolTable.begin();
00352 bool mainExists = false;
00353
00354 while(i != this->symbolTable.end()) {
00355 if((*i).first[0] == '@') {
00356 cerr << "Existem identificadores invalidos\n";
00357 exit(1);
00358 }
00359 if(!mainExists && ((*i).first == "main") && ((*i).second->getTypeCode() == Type::PROCESS)) {
00360 mainExists = true;
00361 }
00362 i++;
00363 }
00364
00365 if(!mainExists) {
00366 cerr << "Tem que haver um processo chamado \"main\"\n";
00367 exit(1);
00368 }
00369
00370 return v;
00371 }
00372
00373 VisitorReturn *TypeCheckerVisitor::visitRangeType(RangeType *rangeType) {
00374 VisitorReturn *v= new VisitorReturn;
00375 return v;
00376 }
00377
00378 VisitorReturn *TypeCheckerVisitor::visitReceiveStatement(ReceiveStatement *receiveStatement) {
00379 VisitorReturn *v= new VisitorReturn;
00380 v = receiveStatement->getMsgId()->visit(*this);
00381 if(v->type->getTypeCode() != Type::MESSAGE) {
00382 cerr << "O identifier não representa uma mensagem\n";
00383 exit(1);
00384 }
00385 v = receiveStatement->getAddrId()->visit(*this);
00386 if(v->type->getTypeCode() != Type::ADDRESS) {
00387 cerr << "O identifier não representa um ADDRESS\n";
00388 exit(1);
00389 }
00390 return v;
00391 }
00392
00393 VisitorReturn *TypeCheckerVisitor::visitSendStatement(SendStatement *sendStatement) {
00394 VisitorReturn *v= new VisitorReturn;
00395 v = sendStatement->getMsgId()->visit(*this);
00396 if(v->type->getTypeCode() != Type::MESSAGE) {
00397 cerr << "O identifier não representa uma mensagem\n";
00398 exit(1);
00399 }
00400 v = sendStatement->getAddrId()->visit(*this);
00401 if(v->type->getTypeCode() != Type::ADDRESS) {
00402 cerr << "O identifier não representa um ADDRESS\n";
00403 exit(1);
00404 }
00405 return v;
00406 }
00407
00408 VisitorReturn *TypeCheckerVisitor::visitSequentialAction(SequentialAction *sequentialAction) {
00409 VisitorReturn *v= new VisitorReturn;
00410 sequentialAction->getAction()->visit(*this);
00411 sequentialAction->getSimpleAction()->visit(*this);
00412 return v;
00413 }
00414
00415 VisitorReturn *TypeCheckerVisitor::visitSequentialBehavior(SequentialBehavior *sequentialBehavior) {
00416 VisitorReturn *v= new VisitorReturn;
00417 sequentialBehavior->getBehavior()->visit(*this);
00418 sequentialBehavior->getSimpleBehavior()->visit(*this);
00419 return v;
00420 }
00421
00422 VisitorReturn *TypeCheckerVisitor::visitSequentialDeclaration(SequentialDeclaration *sequentialDeclaration) {
00423 VisitorReturn *v= new VisitorReturn;
00424
00425 if(sequentialDeclaration->getDeclaration())
00426 sequentialDeclaration->getDeclaration()->visit(*this);
00427 if(sequentialDeclaration->getSimpleDeclaration())
00428 sequentialDeclaration->getSimpleDeclaration()->visit(*this);
00429 return v;
00430 }
00431
00432 VisitorReturn *TypeCheckerVisitor::visitSequentialExpressionList(SequentialExpressionList *sequentialExpressionList) {
00433 VisitorReturn *v= new VisitorReturn;
00434
00435 v = sequentialExpressionList->getExpressionList()->visit(*this);
00436 this->stack.push_back(v->type);
00437 v = sequentialExpressionList->getSimpleExpressionList()->visit(*this);
00438 this->stack.push_back(v->type);
00439
00440 return v;
00441 }
00442
00443 VisitorReturn *TypeCheckerVisitor::visitSequentialFieldDeclaration(SequentialFieldDeclaration *sequentialFieldDeclaration) {
00444 VisitorReturn *v= new VisitorReturn;
00445
00446 sequentialFieldDeclaration->getFieldDeclaration()->visit(*this);
00447 sequentialFieldDeclaration->getSimpleFieldDeclaration()->visit(*this);
00448
00449 return v;
00450 }
00451
00452 VisitorReturn *TypeCheckerVisitor::visitSequentialGuardedStatement(SequentialGuardedStatement *sequentialGuardedStatement) {
00453 VisitorReturn *v= new VisitorReturn;
00454
00455 sequentialGuardedStatement->getGuardedStatement()->visit(*this);
00456 sequentialGuardedStatement->getSimpleGuardedStatement()->visit(*this);
00457
00458 return v;
00459 }
00460
00461 VisitorReturn *TypeCheckerVisitor::visitSequentialIdentifierList(SequentialIdentifierList *sequentialIdentifierList) {
00462 VisitorReturn *v= new VisitorReturn;
00463
00464 sequentialIdentifierList->getIdentifierList()->visit(*this);
00465 sequentialIdentifierList->getSimpleIdentifierList()->visit(*this);
00466
00467 return v;
00468 }
00469
00470 VisitorReturn *TypeCheckerVisitor::visitSequentialImport(SequentialImport *sequentialImport) {
00471 VisitorReturn *v= new VisitorReturn;
00472
00473 sequentialImport->getImport()->visit(*this);
00474 sequentialImport->getSimpleImport()->visit(*this);
00475
00476 return v;
00477 }
00478
00479 VisitorReturn *TypeCheckerVisitor::visitSequentialLeftSideList(SequentialLeftSideList *sequentialLeftSideList) {
00480 VisitorReturn *v= new VisitorReturn;
00481
00482 v = sequentialLeftSideList->getLeftSideList()->visit(*this);
00483 this->stack.push_back(v->type);
00484 v = sequentialLeftSideList->getSimpleLeftSideList()->visit(*this);
00485 this->stack.push_back(v->type);
00486
00487 return v;
00488 }
00489
00490 VisitorReturn *TypeCheckerVisitor::visitSequentialMessage(SequentialMessage *sequentialMessage) {
00491 VisitorReturn *v= new VisitorReturn;
00492 sequentialMessage->getMessage()->visit(*this);
00493 sequentialMessage->getSimpleMessage()->visit(*this);
00494
00495 return v;
00496 }
00497
00498 VisitorReturn *TypeCheckerVisitor::visitSequentialProcess(SequentialProcess *sequentialProcess) {
00499 VisitorReturn *v= new VisitorReturn;
00500 sequentialProcess->getProcess()->visit(*this);
00501 sequentialProcess->getSimpleProcess()->visit(*this);
00502 return v;
00503 }
00504
00505 VisitorReturn *TypeCheckerVisitor::visitSequentialStatement(SequentialStatement *sequentialStatement) {
00506 VisitorReturn *v= new VisitorReturn;
00507
00508 sequentialStatement->getStatement()->visit(*this);
00509 sequentialStatement->getSimpleStatement()->visit(*this);
00510
00511 return v;
00512 }
00513
00514 VisitorReturn *TypeCheckerVisitor::visitSimpleAction(SimpleAction *simpleAction) {
00515 VisitorReturn *v= new VisitorReturn;
00516
00517 simpleAction->getGuard()->visit(*this);
00518 simpleAction->getStatement()->visit(*this);
00519
00520 return v;
00521 }
00522
00523 VisitorReturn *TypeCheckerVisitor::visitSimpleArrayReference(SimpleArrayReference *simpleArrayReference) {
00524 VisitorReturn *v1, *v2;
00525
00526 v1 = simpleArrayReference->getIdentifier()->visit(*this);
00527 if(v1->type->getTypeCode() != Type::ARRAY) {
00528 cerr << "Identifier tem que ser ARRAY\n";
00529 exit(1);
00530 }
00531 v2 = simpleArrayReference->getExpression()->visit(*this);
00532 if(v2->type->getTypeCode() != Type::INTEGER) {
00533 cerr << "Expressao tem que ser INTEGER\n";
00534 exit(1);
00535 }
00536 ArrayType *arrayType = (ArrayType*)v1->type;
00537
00538 Type *type = new Type(simpleArrayReference->getPosition(), arrayType->getType()->getTypeCode());
00539 v1->type = type;
00540
00541 return v1;
00542 }
00543
00544 VisitorReturn *TypeCheckerVisitor::visitSimpleBehavior(SimpleBehavior *simpleBehavior) {
00545 VisitorReturn *v= new VisitorReturn;
00546 Type *type = new Type(simpleBehavior->getPosition(), Type::BEHAVIOR);
00547
00548 this->stack.push_back(type);
00549 this->insert = true;
00550 simpleBehavior->getIdentifierList()->visit(*this);
00551 this->stack.pop_back();
00552 this->insert = false;
00553 return v;
00554 }
00555
00556 VisitorReturn *TypeCheckerVisitor::visitSimpleDeclaration(SimpleDeclaration *simpleDeclaration) {
00557 VisitorReturn *v1, *v2;
00558
00559 this->stack.push_back(simpleDeclaration->getType());
00560 this->insert = true;
00561
00562 simpleDeclaration->getIdentifierList()->visit(*this);
00563 this->stack.pop_back();
00564 this->insert = false;
00565
00566
00567 v2 = simpleDeclaration->getType()->visit(*this);
00568 if(simpleDeclaration->getExpression()) {
00569 v1 = simpleDeclaration->getExpression()->visit(*this);
00570
00571 if(v1->type->getTypeCode() != v2->type->getTypeCode()) {
00572 cerr << "Declaracao e expressao tem tipos diferentes\n";
00573 exit(1);
00574 }
00575 }
00576
00577 return v2;
00578 }
00579
00580 VisitorReturn *TypeCheckerVisitor::visitSimpleExpressionList(SimpleExpressionList *simpleExpressionList) {
00581 VisitorReturn *v= new VisitorReturn;
00582 v = simpleExpressionList->getExpression()->visit(*this);
00583 return v;
00584 }
00585
00586 VisitorReturn *TypeCheckerVisitor::visitSimpleFieldDeclaration(SimpleFieldDeclaration *simpleFieldDeclaration) {
00587 VisitorReturn *v1, *v2;
00588 SimpleMessage *sm;
00589 string str;
00590
00591
00592 v2 = simpleFieldDeclaration->getFieldType()->visit(*this);
00593
00594 if(simpleFieldDeclaration->getExpression()) {
00595 v1 = simpleFieldDeclaration->getExpression()->visit(*this);
00596
00597 if(v1->type->getTypeCode() != v2->type->getTypeCode()) {
00598 cerr << "Declaracao e expressao tem tipos diferentes\n";
00599 exit(1);
00600 }
00601 }
00602
00603 sm = (SimpleMessage *)this->stack[this->stack.size()-1];
00604 str = sm->getIdentifier()->getName() + "." + simpleFieldDeclaration->getIdentifier()->getName();
00605
00606 map<string, Type*>::iterator i = this->symbolTable.find(str);
00607 if(i != this->symbolTable.end()) {
00608 cerr << "Nome do campo já existe\n";
00609 exit(1);
00610 }
00611
00612 this->symbolTable[str] = v2->type;
00613
00614 return v2;
00615 }
00616
00617 VisitorReturn *TypeCheckerVisitor::visitSimpleGuardedStatement(SimpleGuardedStatement *simpleGuardedStatement) {
00618 VisitorReturn *v= new VisitorReturn;
00619
00620
00621 simpleGuardedStatement->getStatement()->visit(*this);
00622
00623 v = simpleGuardedStatement->getExpression()->visit(*this);
00624 if(v->type->getTypeCode() != Type::BOOLEAN) {
00625 cerr << "A guarda tem que conter uma expressao booleana \\_:D_/\n";
00626 exit(1);
00627 }
00628
00629 return v;
00630 }
00631
00632 VisitorReturn *TypeCheckerVisitor::visitSimpleIdentifierList(SimpleIdentifierList *simpleIdentifierList) {
00633 VisitorReturn *v= new VisitorReturn;
00634 simpleIdentifierList->getIdentifier()->visit(*this);
00635 return v;
00636 }
00637
00638 VisitorReturn *TypeCheckerVisitor::visitSimpleImport(SimpleImport *simpleImport) {
00639 VisitorReturn *v= new VisitorReturn;
00640 return v;
00641 }
00642
00643 VisitorReturn *TypeCheckerVisitor::visitSimpleLeftSideList(SimpleLeftSideList *simpleLeftSideList) {
00644 VisitorReturn *v= new VisitorReturn;
00645 v = simpleLeftSideList->getLeftSide()->visit(*this);
00646 return v;
00647 }
00648
00649 VisitorReturn *TypeCheckerVisitor::visitSimpleMessage(SimpleMessage *simpleMessage) {
00650 VisitorReturn *v= new VisitorReturn;
00651 Type *type = new Type(simpleMessage->getPosition(), Type::MESSAGE);
00652
00653 this->stack.push_back(simpleMessage);
00654 this->stack.push_back(type);
00655 this->insert = true;
00656 simpleMessage->getIdentifier()->visit(*this);
00657 this->stack.pop_back();
00658 this->insert = false;
00659
00660 simpleMessage->getFieldDeclaration()->visit(*this);
00661 this->stack.pop_back();
00662
00663 return v;
00664 }
00665
00666 VisitorReturn *TypeCheckerVisitor::visitSimpleProcess(SimpleProcess *simpleProcess) {
00667 VisitorReturn *v= new VisitorReturn;
00668 Type *type = new Type(simpleProcess->getPosition(), Type::PROCESS);
00669
00670 this->stack.push_back(type);
00671 this->insert = true;
00672 v = simpleProcess->getIdentifier()->visit(*this);
00673 this->stack.pop_back();
00674 this->insert = false;
00675
00676 string str = "@";
00677
00678 str += simpleProcess->getIdentifier()->getName();
00679 map<string, Type*>::iterator i = this->symbolTable.find(str);
00680 if(i != this->symbolTable.end()) {
00681 this->symbolTable.erase(str);
00682 }
00683
00684 simpleProcess->getDeclaration()->visit(*this);
00685 simpleProcess->getAction()->visit(*this);
00686
00687 return v;
00688 }
00689
00690 VisitorReturn *TypeCheckerVisitor::visitSimpleStatement(SimpleStatement *simpleStatement) {
00691 VisitorReturn *v= new VisitorReturn;
00692 return v;
00693 }
00694
00695 VisitorReturn *TypeCheckerVisitor::visitSkipStatement(SkipStatement *skipStatement) {
00696 VisitorReturn *v= new VisitorReturn;
00697 return v;
00698 }
00699
00700 VisitorReturn *TypeCheckerVisitor::visitStartStatement(StartStatement *startStatement) {
00701 VisitorReturn *v= new VisitorReturn;
00702 string str = "@";
00703
00704 str += startStatement->getIdentifier()->getName();
00705 map<string, Type*>::iterator i = this->symbolTable.find(str);
00706 if(i == this->symbolTable.end()) {
00707 this->symbolTable[str] = new Type(startStatement->getPosition(),Type::PROCESS);
00708 } else {
00709 v = startStatement->getIdentifier()->visit(*this);
00710 if(v->type->getTypeCode() != Type::PROCESS) {
00711 cerr << "Identificador tem que ser um processo \\_:D_/\n";
00712 exit(1);
00713 }
00714 }
00715
00716 return v;
00717 }
00718
00719 VisitorReturn *TypeCheckerVisitor::visitStatement(Statement *statement) {
00720 VisitorReturn *v= new VisitorReturn;
00721 return v;
00722 }
00723
00724 VisitorReturn *TypeCheckerVisitor::visitStopStatement(StopStatement *stopStatement) {
00725 VisitorReturn *v= new VisitorReturn;
00726 return v;
00727 }
00728
00729 VisitorReturn *TypeCheckerVisitor::visitStringLiteral(StringLiteral *stringLiteral) {
00730 VisitorReturn *v= new VisitorReturn;
00731 v->type = new Type(stringLiteral->getPosition(),Type::STRING);
00732 return v;
00733 }
00734
00735 VisitorReturn *TypeCheckerVisitor::visitIntegerLiteral(IntegerLiteral *integerLiteral) {
00736 VisitorReturn *v= new VisitorReturn;
00737 v->type = new Type(integerLiteral->getPosition(),Type::INTEGER);
00738 return v;
00739 }
00740
00741 VisitorReturn *TypeCheckerVisitor::visitType(Type *type) {
00742 VisitorReturn *v= new VisitorReturn;
00743 v->type = type;
00744 return v;
00745 }
00746
00747 VisitorReturn *TypeCheckerVisitor::visitUnaryExpression(UnaryExpression *unaryExpression) {
00748 VisitorReturn *v= new VisitorReturn;
00749 string op;
00750
00751 v = unaryExpression->getExpression()->visit(*this);
00752 op = unaryExpression->getOp();
00753
00754 if(op == "~") {
00755 if(v->type->getTypeCode() != Type::BOOLEAN) {
00756 cerr << "Operadores booleanos aplicados a expressões não booleanas\n";
00757 exit(1);
00758 }
00759 } else {
00760 if(v->type->getTypeCode() != Type::INTEGER) {
00761 cerr << "Operadores aritmeticos aplicados a expressões não inteiras\n";
00762 exit(1);
00763 }
00764 }
00765
00766
00767 return v;
00768 }
00769