diff --git a/MEPA b/MEPA
index a4aa4861f3d81f46d57aa23d9de15d9c87adcf82..a8c5494d15982a373895918ab41677a0c247bc79 100644
--- a/MEPA
+++ b/MEPA
@@ -10,14 +10,14 @@ R02: NADA
      CRCT 1
      ARMI 1,-5
      DMEM 1
+     RTPR 1,2
 R00: NADA 
-     AMEM 1
+     CRCT 8
+     ARMZ 0,0
      CREN 0,0
      CRCT 2
      CRCT 3
      SOMA
-     CHPR R01,1
-     CRVL 1,-6
-     ARMZ 0,0
+     CHPR R01,0
      DMEM 1
      PARA
diff --git a/compilador b/compilador
index ea2bab45adb9f6e6ebb169ff830776d45c59415a..4dbcf1715206b3c6730c7da8132228ccd1f1e9f4 100755
Binary files a/compilador and b/compilador differ
diff --git a/compilador.tab.c b/compilador.tab.c
index fe1feacadd35989e3de27121b456723e562c297f..3499d0d553d3dc396b86ba2a573be6b674f4a85a 100644
--- a/compilador.tab.c
+++ b/compilador.tab.c
@@ -567,11 +567,11 @@ static const yytype_int16 yyrline[] =
      234,   238,   210,   246,   247,   245,   255,   258,   259,   263,
      262,   272,   272,   280,   281,   284,   294,   297,   298,   299,
      302,   303,   306,   307,   308,   309,   310,   311,   314,   314,
-     318,   319,   322,   322,   345,   345,   388,   391,   395,   394,
-     407,   407,   421,   424,   425,   428,   437,   440,   443,   448,
-     451,   454,   457,   460,   463,   466,   469,   475,   481,   484,
-     487,   490,   493,   493,   524,   535,   537,   544,   537,   570,
-     577,   579,   582,   582
+     318,   319,   322,   322,   353,   353,   396,   399,   403,   402,
+     415,   415,   429,   432,   433,   436,   445,   448,   451,   456,
+     459,   462,   465,   468,   471,   474,   477,   483,   489,   492,
+     495,   498,   501,   501,   543,   554,   556,   563,   556,   589,
+     596,   598,   601,   601
 };
 #endif
 
@@ -1536,7 +1536,7 @@ yyreduce:
             desloc = retira_vs_pf(ts);
             geraCodigo(NULL,buffer);
             if (nivel_lexico > 0)
-               nivel_lexico += 1;
+               nivel_lexico -= 1;
             mostra_ts(ts);
          }
 #line 1543 "compilador.tab.c"
@@ -1773,18 +1773,26 @@ yyreduce:
     if (l_elem == NULL) {
         yyerror("Variável de destino não declarada");
     } else {
-        if (l_elem->categ == PF && l_elem->info.pf.passagem == REF)
+         if (l_elem->categ == PF && l_elem->info.pf.passagem == REF)
             atr_indireto = REF;
          else atr_indireto = VLR; 
-        destino_nivel = l_elem->nivel;
-        destino_desloc = l_elem->info.vs.desloc;
+         destino_nivel = l_elem->nivel;
+         if(l_elem->categ == VS)
+            destino_desloc = l_elem->info.vs.desloc;
+         else if(l_elem->categ == PF)
+            destino_desloc = l_elem->info.pf.desloc;
+         else if(l_elem->categ == FUN)
+            destino_desloc = l_elem->info.fun.desloc;
+         else
+            yyerror("Tentativa de atribuir em procedimento");
+
     }
 }
-#line 1784 "compilador.tab.c"
+#line 1792 "compilador.tab.c"
     break;
 
   case 63:
-#line 332 "compilador.y"
+#line 340 "compilador.y"
                                {
     // Gera código ARMZ para armazenar valor
     char buffer[50];
@@ -1795,11 +1803,11 @@ yyreduce:
     }
     geraCodigo(NULL, buffer);
 }
-#line 1799 "compilador.tab.c"
+#line 1807 "compilador.tab.c"
     break;
 
   case 64:
-#line 345 "compilador.y"
+#line 353 "compilador.y"
             {
                if (l_elem == NULL){
                   yyerror("Procedimento não declarado");
@@ -1811,11 +1819,11 @@ yyreduce:
                   geraCodigo(NULL, "AMEM 1");
                num_param = 0; // Reinicia a contagem de parâmetros reais   
             }
-#line 1815 "compilador.tab.c"
+#line 1823 "compilador.tab.c"
     break;
 
   case 65:
-#line 359 "compilador.y"
+#line 367 "compilador.y"
             { 
                if (l_elem->categ == PR || l_elem->categ ==FUN) {
                   char buffer[50];
@@ -1843,11 +1851,11 @@ yyreduce:
                   geraCodigo(NULL, buffer);
                }
             }
-#line 1847 "compilador.tab.c"
+#line 1855 "compilador.tab.c"
     break;
 
   case 68:
-#line 395 "compilador.y"
+#line 403 "compilador.y"
                {
                   char buffer[50];
                   desempilha(buffer,proc);
@@ -1855,20 +1863,20 @@ yyreduce:
                   val_ou_ref = l_elem->info.pr.param[num_param][1];
                   empilha(buffer,proc);
                }
-#line 1859 "compilador.tab.c"
+#line 1867 "compilador.tab.c"
     break;
 
   case 69:
-#line 403 "compilador.y"
+#line 411 "compilador.y"
                {
                   num_param++; // Incrementa para cada parâmetro real
                   val_ou_ref = VLR;
                }
-#line 1868 "compilador.tab.c"
+#line 1876 "compilador.tab.c"
     break;
 
   case 70:
-#line 407 "compilador.y"
+#line 415 "compilador.y"
                  {
                   char buffer[50];
                   desempilha(buffer,proc);
@@ -1876,20 +1884,20 @@ yyreduce:
                   val_ou_ref = l_elem->info.pr.param[num_param][1];
                   empilha(buffer,proc);
                }
-#line 1880 "compilador.tab.c"
+#line 1888 "compilador.tab.c"
     break;
 
   case 71:
-#line 415 "compilador.y"
+#line 423 "compilador.y"
                {
                   num_param++; // Conta o primeiro parâmetro real
                   val_ou_ref = VLR;
                }
-#line 1889 "compilador.tab.c"
+#line 1897 "compilador.tab.c"
     break;
 
   case 75:
-#line 428 "compilador.y"
+#line 436 "compilador.y"
                     {
                geraCodigo(NULL, "LEIT");
                l_elem = busca(token,ts);
@@ -1897,123 +1905,123 @@ yyreduce:
                sprintf(buffer,"ARMZ %d,%d",l_elem->nivel,l_elem->info.vs.desloc);
                geraCodigo(NULL,buffer);
             }
-#line 1901 "compilador.tab.c"
+#line 1909 "compilador.tab.c"
     break;
 
   case 77:
-#line 440 "compilador.y"
+#line 448 "compilador.y"
                                                          {
                geraCodigo(NULL,"IMPR");
             }
-#line 1909 "compilador.tab.c"
+#line 1917 "compilador.tab.c"
     break;
 
   case 78:
-#line 443 "compilador.y"
+#line 451 "compilador.y"
                                 {
                geraCodigo(NULL,"IMPR");
             }
-#line 1917 "compilador.tab.c"
+#line 1925 "compilador.tab.c"
     break;
 
   case 79:
-#line 448 "compilador.y"
+#line 456 "compilador.y"
                                              {
             geraCodigo(NULL, "CMIG"); // Adiciona operação de cmig
          }
-#line 1925 "compilador.tab.c"
+#line 1933 "compilador.tab.c"
     break;
 
   case 80:
-#line 451 "compilador.y"
+#line 459 "compilador.y"
                                                 {
             geraCodigo(NULL, "CMDG"); // Adiciona operação de cmdg
          }
-#line 1933 "compilador.tab.c"
+#line 1941 "compilador.tab.c"
     break;
 
   case 81:
-#line 454 "compilador.y"
+#line 462 "compilador.y"
                                              {
             geraCodigo(NULL, "CMME"); // Adiciona operação de cmme
          }
-#line 1941 "compilador.tab.c"
+#line 1949 "compilador.tab.c"
     break;
 
   case 82:
-#line 457 "compilador.y"
+#line 465 "compilador.y"
                                                    {
             geraCodigo(NULL, "CMEG"); // Adiciona operação de cmeg
          }
-#line 1949 "compilador.tab.c"
+#line 1957 "compilador.tab.c"
     break;
 
   case 83:
-#line 460 "compilador.y"
+#line 468 "compilador.y"
                                              {
             geraCodigo(NULL, "CMMA"); // Adiciona operação de cmma
          }
-#line 1957 "compilador.tab.c"
+#line 1965 "compilador.tab.c"
     break;
 
   case 84:
-#line 463 "compilador.y"
+#line 471 "compilador.y"
                                                    {
             geraCodigo(NULL, "CMAG"); // Adiciona operação de cmag
          }
-#line 1965 "compilador.tab.c"
+#line 1973 "compilador.tab.c"
     break;
 
   case 86:
-#line 469 "compilador.y"
+#line 477 "compilador.y"
                                                 {
                if (val_ou_ref == REF)
                   yyerror("Erro: tentativa de EXPRESSAO em passagem por REFERENCIA\n");
                else
                   geraCodigo(NULL, "SOMA"); // Adiciona operação de soma
             }
-#line 1976 "compilador.tab.c"
+#line 1984 "compilador.tab.c"
     break;
 
   case 87:
-#line 475 "compilador.y"
+#line 483 "compilador.y"
                                             {
                if (val_ou_ref == REF)
                   yyerror("Erro: tentativa de EXPRESSAO em passagem por REFERENCIA\n");
                else
                   geraCodigo(NULL, "SUBT"); // Adiciona operação de subt
             }
-#line 1987 "compilador.tab.c"
+#line 1995 "compilador.tab.c"
     break;
 
   case 89:
-#line 484 "compilador.y"
+#line 492 "compilador.y"
                              {
                geraCodigo(NULL, "MULT"); // Adiciona operação de mult
             }
-#line 1995 "compilador.tab.c"
+#line 2003 "compilador.tab.c"
     break;
 
   case 90:
-#line 487 "compilador.y"
+#line 495 "compilador.y"
                               {
                geraCodigo(NULL, "DIVI"); // Adiciona operação de divi
             }
-#line 2003 "compilador.tab.c"
+#line 2011 "compilador.tab.c"
     break;
 
   case 92:
-#line 493 "compilador.y"
+#line 501 "compilador.y"
              {
     // Carrega variável
     l_elem = busca(token, ts);
     empilha(token, proc);
    }
-#line 2013 "compilador.tab.c"
+#line 2021 "compilador.tab.c"
     break;
 
   case 93:
-#line 499 "compilador.y"
+#line 507 "compilador.y"
    {
       char buffer[50];
       desempilha(buffer, proc);
@@ -2022,28 +2030,39 @@ yyreduce:
          yyerror("Variável não declarada");
       } else {
          if (val_ou_ref == REF) {
-               if (l_elem->categ == VS) 
+               if (l_elem->categ == VS){
                   sprintf(buffer, "CREN %d,%d", l_elem->nivel, l_elem->info.vs.desloc);
-               else if (l_elem->categ == FUN)
-                  sprintf(buffer, "CREN %d,%d", l_elem->nivel, l_elem->info.fun.desloc);
+                  geraCodigo(NULL, buffer);
+               }
+               else if (l_elem->categ == PF){
+                  sprintf(buffer, "CREN %d,%d", l_elem->nivel, l_elem->info.pf.desloc);
+                  geraCodigo(NULL, buffer);
+               }
+               else
+                  yyerror("Tentativa de passagem de referencia de procedimento ou funcao");
+               
          } 
          else if (l_elem->categ == PF && l_elem->info.pf.passagem == REF) {
                sprintf(buffer, "CRVI %d,%d", l_elem->nivel, l_elem->info.pf.desloc);
+               geraCodigo(NULL, buffer);
          }        
          else {
-               if (l_elem->categ == VS) 
+               if (l_elem->categ == VS) {
                   sprintf(buffer, "CRVL %d,%d", l_elem->nivel, l_elem->info.vs.desloc);
-               else if (l_elem->categ == FUN)
-                  sprintf(buffer, "CRVL %d,%d", l_elem->nivel, l_elem->info.fun.desloc);
+                  geraCodigo(NULL, buffer);
+               }
+               else if (l_elem->categ == PF){
+                  sprintf(buffer, "CRVL %d,%d", l_elem->nivel, l_elem->info.pf.desloc);
+                  geraCodigo(NULL, buffer);
+               }
          }
-         geraCodigo(NULL, buffer);
       }
    }
-#line 2043 "compilador.tab.c"
+#line 2062 "compilador.tab.c"
     break;
 
   case 94:
-#line 524 "compilador.y"
+#line 543 "compilador.y"
          {
     // Empilha constante
     char buffer[50];
@@ -2054,11 +2073,11 @@ yyreduce:
     }
     geraCodigo(NULL, buffer);
 }
-#line 2058 "compilador.tab.c"
+#line 2077 "compilador.tab.c"
     break;
 
   case 96:
-#line 537 "compilador.y"
+#line 556 "compilador.y"
                     {
                char r_ini[4];
                sprintf(r_ini, "R%02d", rot_id);
@@ -2066,11 +2085,11 @@ yyreduce:
                rot_id += 1;
                geraCodigo(r_ini,"NADA");
             }
-#line 2070 "compilador.tab.c"
+#line 2089 "compilador.tab.c"
     break;
 
   case 97:
-#line 544 "compilador.y"
+#line 563 "compilador.y"
                                {
                char r_fim[4];
                sprintf(r_fim, "R%02d", rot_id);
@@ -2081,11 +2100,11 @@ yyreduce:
                strcat(buffer,r_fim);
                geraCodigo(NULL,buffer);
             }
-#line 2085 "compilador.tab.c"
+#line 2104 "compilador.tab.c"
     break;
 
   case 98:
-#line 554 "compilador.y"
+#line 573 "compilador.y"
                                {
                char r_ini[4];
                char r_fim[4];
@@ -2100,21 +2119,21 @@ yyreduce:
 
                geraCodigo(r_fim,"NADA");
             }
-#line 2104 "compilador.tab.c"
+#line 2123 "compilador.tab.c"
     break;
 
   case 99:
-#line 570 "compilador.y"
+#line 589 "compilador.y"
                                        {
                char r_fim[4];
                desempilha(r_fim,rot);
                geraCodigo(r_fim,"NADA");
             }
-#line 2114 "compilador.tab.c"
+#line 2133 "compilador.tab.c"
     break;
 
   case 102:
-#line 582 "compilador.y"
+#line 601 "compilador.y"
                       {
                char r_else[4];
                sprintf(r_else,"R%02d",rot_id);
@@ -2130,11 +2149,11 @@ yyreduce:
                empilha(r_fim, rot);
                rot_id += 1;
             }
-#line 2134 "compilador.tab.c"
+#line 2153 "compilador.tab.c"
     break;
 
   case 103:
-#line 597 "compilador.y"
+#line 616 "compilador.y"
                                     {
                char r_fim[4];
                desempilha(r_fim,rot);
@@ -2149,11 +2168,11 @@ yyreduce:
 
                geraCodigo(r_else,"NADA");
             }
-#line 2153 "compilador.tab.c"
+#line 2172 "compilador.tab.c"
     break;
 
 
-#line 2157 "compilador.tab.c"
+#line 2176 "compilador.tab.c"
 
       default: break;
     }
@@ -2385,7 +2404,7 @@ yyreturn:
 #endif
   return yyresult;
 }
-#line 614 "compilador.y"
+#line 633 "compilador.y"
 
 
 int main (int argc, char** argv) {
diff --git a/compilador.y b/compilador.y
index 50d3bdd381670088718ced83b99ef572d488bf1b..1821ddda7f93263d02a9488db66c65169fe6d21f 100644
--- a/compilador.y
+++ b/compilador.y
@@ -84,7 +84,7 @@ bloco       :
             desloc = retira_vs_pf(ts);
             geraCodigo(NULL,buffer);
             if (nivel_lexico > 0)
-               nivel_lexico += 1;
+               nivel_lexico -= 1;
             mostra_ts(ts);
          }
 ;
@@ -323,11 +323,19 @@ atribuicao: {
     if (l_elem == NULL) {
         yyerror("Variável de destino não declarada");
     } else {
-        if (l_elem->categ == PF && l_elem->info.pf.passagem == REF)
+         if (l_elem->categ == PF && l_elem->info.pf.passagem == REF)
             atr_indireto = REF;
          else atr_indireto = VLR; 
-        destino_nivel = l_elem->nivel;
-        destino_desloc = l_elem->info.vs.desloc;
+         destino_nivel = l_elem->nivel;
+         if(l_elem->categ == VS)
+            destino_desloc = l_elem->info.vs.desloc;
+         else if(l_elem->categ == PF)
+            destino_desloc = l_elem->info.pf.desloc;
+         else if(l_elem->categ == FUN)
+            destino_desloc = l_elem->info.fun.desloc;
+         else
+            yyerror("Tentativa de atribuir em procedimento");
+
     }
 } ATRIBUICAO expressao_simples {
     // Gera código ARMZ para armazenar valor
@@ -504,21 +512,32 @@ fator: IDENT {
          yyerror("Variável não declarada");
       } else {
          if (val_ou_ref == REF) {
-               if (l_elem->categ == VS) 
+               if (l_elem->categ == VS){
                   sprintf(buffer, "CREN %d,%d", l_elem->nivel, l_elem->info.vs.desloc);
-               else if (l_elem->categ == FUN)
-                  sprintf(buffer, "CREN %d,%d", l_elem->nivel, l_elem->info.fun.desloc);
+                  geraCodigo(NULL, buffer);
+               }
+               else if (l_elem->categ == PF){
+                  sprintf(buffer, "CREN %d,%d", l_elem->nivel, l_elem->info.pf.desloc);
+                  geraCodigo(NULL, buffer);
+               }
+               else
+                  yyerror("Tentativa de passagem de referencia de procedimento ou funcao");
+               
          } 
          else if (l_elem->categ == PF && l_elem->info.pf.passagem == REF) {
                sprintf(buffer, "CRVI %d,%d", l_elem->nivel, l_elem->info.pf.desloc);
+               geraCodigo(NULL, buffer);
          }        
          else {
-               if (l_elem->categ == VS) 
+               if (l_elem->categ == VS) {
                   sprintf(buffer, "CRVL %d,%d", l_elem->nivel, l_elem->info.vs.desloc);
-               else if (l_elem->categ == FUN)
-                  sprintf(buffer, "CRVL %d,%d", l_elem->nivel, l_elem->info.fun.desloc);
+                  geraCodigo(NULL, buffer);
+               }
+               else if (l_elem->categ == PF){
+                  sprintf(buffer, "CRVL %d,%d", l_elem->nivel, l_elem->info.pf.desloc);
+                  geraCodigo(NULL, buffer);
+               }
          }
-         geraCodigo(NULL, buffer);
       }
    }
 | NUMERO {
diff --git a/teste10.pas b/teste10.pas
index 339526fc4d838906e237c5f415cf214bb39ad39e..3c1b11b46040a491083a26b9d7adac84d12e47c0 100644
--- a/teste10.pas
+++ b/teste10.pas
@@ -5,6 +5,7 @@ program proc1 (input, output);
     begin
         z := a;
         a := 1;
+        f := a;
     end;
 begin
     x := f(x, 2+3);
diff --git a/teste11.pas b/teste11.pas
new file mode 100644
index 0000000000000000000000000000000000000000..a0e801c42bc98455cd021a9a01cecb8c06b6e9b1
--- /dev/null
+++ b/teste11.pas
@@ -0,0 +1,22 @@
+program funcao (input, output); 
+var  m: integer;      
+function f(n: integer; var k: integer): integer; 
+var p, q: integer;           
+begin                    
+   if n<2 then
+      begin          
+         f:=n; k:=0;     
+      end              
+   else                
+      begin            
+         f:=f(n-1,p) + f(n-2,q);   
+         k:=p+q+1;      
+      end;             
+   write(n,k);        
+end;                      
+begin                          
+   write(f(3,m),m); 
+end. 
+
+
+
diff --git a/teste5.pas b/teste5.pas
index 940451a66aa717183213a16fc93e922da02ef704..358a19da28f0812fda57126787eec514c3f4c37b 100644
--- a/teste5.pas
+++ b/teste5.pas
@@ -12,7 +12,7 @@ begin
           if i = 0
             then write(2)
             else write(3);
-         end
+         end;
         else  write(i,1);
       i := i+1;             
    end;