📄 interpret.c
字号:
/* Interpret.c par Grobost Fr閐閞ick */#include <stdio.h>#include <stdlib.h>#include <ast.h>#include <interpret.h>int BreakError=0; /* pour savoir si un break est lu a l'exterieur d'une boucle, et ne fait rien */int ContinueError=0; /* pour savoir si un continu est lu a l'exterieur d'une boucle */int BreakRead=0; /* pour savoir si un break a ete lu */int ContinueRead=0; /* pour savoir si un Continu a ete lu */void EvalStmtList(stmtList s);void EvalStmt(statement s);int EvalBoolExpr(boolExpr e);int EvalArithExpr(arithExpr e);int EvalArithBinaryOp(int a,int b,arithBinaryOp operateur);int EvalBoolBinaryOp(int a,int b,boolBinaryOp operateur);int EvalBoolUnaryOp(int a,boolBinaryOp operateur);/* Pour savoir si l'on est a l'interieur d'une boucle */int in_boucle = 0;/* -- Fonction principale de l'Interpreteur -- */void interpretProgram(program p) { printf("\n # ---- # Interpretation du program \"%s\" realisee par Grobost Frederick # ---- # \n \n",programGetName(p)); declList decl=programGetDecls(p); declListGoToHead(decl); while( declListHasMoreElt(decl) ) { if(!symbtabIsMember(declListGetCurrent(decl))) symbtabAddElt(declListGetCurrent(decl),0); declListMoveCurrent(decl); } EvalStmtList(programGetStmts(p));}/* -- Fonction permettant de lire la liste des statements -- */void EvalStmtList(stmtList s) { if(BreakRead!=0) /* Si un break est lu, on arrete tout */ return; if(ContinueRead!=0) { stmtListGoToEnd(s); } stmtListGoToHead(s); while(stmtListHasMoreElt(s)) { EvalStmt(stmtListGetCurrent(s)); /* On interprete le statement */ stmtListMoveCurrent(s); }}/* -- Fonction qui va interpreter le statement -- */void EvalStmt(statement s) { switch(stmtGetType(s)) { /* On traite le cas du PRINT */ case PRINT: printf("%s : %i \n",stmtGetPrint(s),symbtabGetValue(stmtGetPrint(s))); break; /* On traite le cas de l'affectation ASSIGN */ case ASSIGN: symbtabUpdate(stmtGetAssignIdent(s),EvalArithExpr(stmtGetAssignExpr(s))); break; /* On traite le cas du IF */ case COND: if(EvalBoolExpr(stmtGetCondExp(s))) EvalStmt(stmtGetCondThen(s)); else if(stmtGetType(stmtGetCondElse(s))!=EMPTY) EvalStmt(stmtGetCondElse(s)); break; /* On traite le cas du WHILE */ case WHILE: in_boucle++; /* on incremente notre variable pour bien signifier qu'on est a linterieur d'une boucle */ while(EvalBoolExpr(stmtGetWhileExp(s)) && BreakRead==0) { EvalStmt(stmtGetWhileBody(s)); } /* en sortant de la boucle, je remets mes variables a 0 */ BreakRead=0; ContinueRead=0; /*on decrement notre compteur */ in_boucle--; break; /* On traite le cas du BLOCK */ case BLOCK: EvalStmtList(stmtGetBlock(s)); break; case BREAK: if(in_boucle!=0) /* on teste si l'on est dans une boucle */ BreakRead=1; /* on met la variable BreakRead a 1, ce qui stoppera l'execution des statements dans notre boucle, (test dans le case du while) */ else BreakError=1; /* cela veut dire qu'un break est ecrit en dehors d'une boucle, mais cela ne fait rien car je n'utiliserai pas cette variable apres */ break; case CONTINUE: if(in_boucle!=0) ContinueRead=1; else ContinueError=1; break;}}/* -- Fonction interpretant une expression arithmetique -- */int EvalArithExpr(arithExpr e){ switch(arithExprGetType(e)) { case NUMBER: return arithExprGetNumber(e); break; case IDENT: return symbtabGetValue(arithExprGetIdent(e)); break; case BINARY: return EvalArithBinaryOp(EvalArithExpr(arithExprGetBinaryFg(e)),EvalArithExpr(arithExprGetBinaryFd(e)),arithExprGetBinaryOp(e)); break; }}/* -- Fonction pour manipuler une expression booleennes -- */int EvalBoolExpr(boolExpr e) { switch(boolExprGetType(e)) { case BINARYARITHCMPEXPR: return EvalArithBinaryOp(EvalArithExpr(boolExprGetArithBinaryFg(e)), EvalArithExpr(boolExprGetArithBinaryFd(e)), boolExprGetArithBinaryOp(e)); break; case UNARYBOOLEXPR: return EvalBoolUnaryOp(EvalBoolExpr(boolExprGetBoolUnary(e)),boolExprGetBoolUnaryOp(e)); break; case BINARYBOOLEXPR: return EvalBoolBinaryOp(EvalBoolExpr(boolExprGetBoolBinaryFg(e)), EvalBoolExpr(boolExprGetBoolBinaryFd(e)), boolExprGetBoolBinaryOp(e)); break; }}/* -- Fonction effectuant le calcul d'une expression arithmetique/booleenne -- */int EvalArithBinaryOp(int a,int b,arithBinaryOp operateur) { switch(operateur) { case PLUS: return a + b; break; case MINUS: return a-b; break; case TIMES: return a*b; break; case DIVIDE: return a/b; break; case EQUAL: return ((a==b)? 1:0); break; case NOTEQUAL: return ((a!=b)? 1:0); break; case LESS: return ((a<b)? 1:0); break; case LESSEQUAL: return ((a<=b)? 1:0); break; case GREATER: return ((a>b)? 1:0); break; case GREATEREQUAL: return ((a>=b)? 1:0); break; }}int EvalBoolBinaryOp(int a,int b,boolBinaryOp operateur) { switch(operateur) { case AND: return a&&b ; break; case OR: return a||b; break; }}int EvalBoolUnaryOp(int a,boolBinaryOp operateur) { switch(operateur) { case NOT: return ((!a)? 1:0); break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -