ExpType BinExp::getType(CPilaDeSimbolos& stack, CFunctionTable& functable) { ExpType exp1Type = exp1->getType(stack, functable); ExpType exp2Type = exp2->getType(stack, functable); if (evalType() == ET_ARIT) { //Si ambos tipos son iguales, lo devolvemos if (exp1Type == exp2Type) { return exp1Type; } //Si llega aqui, no son iguales, "promocionar" si son float e int if ((exp1Type == ET_INT && exp2Type == ET_FLOAT) || (exp1Type == ET_FLOAT && exp2Type == ET_INT)) { return ET_FLOAT; } } else { if (evalType() == ET_BOOL) { return ET_BOOL; } } //Centinela return ET_UNKNOWN; }
bool checkInstruction(TreeP t) { switch(t->type) { //cas des operateurs binaires case OP: if(!isBinaryTree(t)) { return false; } if((!strcmp(evalType(getChild(t, 0))->nom, "integer")) && (!strcmp(evalType(getChild(t, 1))->nom, "integer"))) { fprintf(stderr, "checkInstruction : operation non conforme (type fils different de entier)\n"); return false; } break; case CAT_STRUCT: if(!isBinaryTree(t)){ return false; } if((!strcmp(evalType(getChild(t, 0))->nom, "string")) && (!strcmp(evalType(getChild(t, 1))->nom, "string"))) { fprintf(stderr, "checkInstruction : concatenation non conforme (type fils different de string)\n"); return false; } break; case ASSIGN_STRUCT: if(!isBinaryTree(t)){ return false; } //verifie que le type du sous-arbre gauche est du meme type que le type du sous-arbre droit if(strcmp(evalType(getChild(t, 0))->nom, evalType(getChild(t, 1))->nom)) { fprintf(stderr, "checkInstruction : affectation non conforme (type fils g & d differents)\n"); return false; } break; //cas des opérateurs unaires case UNARY_STRUCT: if(t->nbChildren != 1) { return false; } if(strcmp(evalType(getChild(t, 0))->nom, "integer")) { fprintf(stderr, "checkInstruction : arbre unaire non conforme (type du fils non entier)\n"); return false; } break; // cas de l'operateur '.' case DOT: case MTDCALL: /* Verifier que ce qu'il y a apres le "." fait bien partie de la classe de ce qu'il y a a gauche */ if(!evalType(t)) { fprintf(stderr, "checkInstruction : partie droite de l'expression avec operateur '.' non valide\n"); return false; } break; //cas de l'operateur If Then Else case ITE: if(t->nbChildren != 3 || (strcmp(evalType(getChild(t, 0))->nom, "integer"))) { fprintf(stderr, "checkInstruction : If Then Else non valide\n"); return false; } if(!checkInstruction(getChild(t, 1)) || !checkInstruction(t->content.children[2])) { return false; } break; case RETURN: if(!checkInstruction(getChild(t, 0))) { return false; } break; case YIELD_STRUCT: if(!checkInstruction(getChild(t, 0))) { return false; } break; default: fprintf(stderr, "Operateur non reconnu"); } return true; }
//fonction qui verifie le type de l'arbre ClasseP evalType(TreeP t) { TreeP tmp = NULL; if(t->type == INTEGER) { return getClasse("integer"); } if(t->type == STRING) { return getClasse("string"); } checkInstruction(t); switch(t->type) { case OP: if((!strcmp(evalType(getChild(t, 0))->nom, "integer")) && (!strcmp(evalType(getChild(t, 1))->nom, "integer"))) return getClasse("integer"); else return NULL; break; case CAT_STRUCT: if((!strcmp(evalType(getChild(t, 0))->nom, "string")) && (!strcmp(evalType(getChild(t, 1))->nom, "string"))) return getClasse("string"); else return NULL; break; case UNARY_STRUCT: if((!strcmp(evalType(getChild(t, 0))->nom, "integer"))) return getClasse("integer"); else return NULL; break; case DOT: if(getChild(t, 1)->nbChildren > 1) { tmp = getChild(getChild(t, 1), 0); if(tmp->type != VAR_STRUCT) return NULL; if(getAttribut(evalType(getChild(t, 0)), tmp->content.var->nom)) return getClasse(tmp->content.var->type); else return NULL; } else { if(getChild(t, 1)->type != VAR_STRUCT) return NULL; if(getAttribut(evalType(getChild(t, 0)), getChild(t, 1)->content.var->nom)) return getClasse(getChild(t, 1)->content.var->type); else return NULL; } case MTDCALL: if(getChild(t, 1)->nbChildren > 1) { tmp = getChild(getChild(t, 1), 0); if(tmp->type != MTD) return NULL; if(getMethode(evalType(getChild(t, 0)), tmp->content.meth->nom)) return getClasse(tmp->content.meth->type); else return NULL; } else { if(getChild(t, 1)->type != MTD) return NULL; if(getMethode(evalType(getChild(t, 0)), getChild(t, 1)->content.meth->nom)) return getClasse(getChild(t, 1)->content.meth->type); else return NULL; } break; default: return NULL; } return 0; }