Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

typecheckervisitor.cpp

Go to the documentation of this file.
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; // essse return nao serve pra nada
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; // essse return nao serve pra nada
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; // esse retormo nao servepra nada
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; // esse retormo nao servepra nada
00615 }
00616 
00617 VisitorReturn *TypeCheckerVisitor::visitSimpleGuardedStatement(SimpleGuardedStatement *simpleGuardedStatement) {
00618         VisitorReturn *v= new VisitorReturn;
00619         
00620         // \_:D_/
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; // \_:)_/   \_:D_/   
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 

Generated on Mon Dec 1 17:00:24 2003 for Protomake by doxygen1.3