From d44c0a3c4e5263d7dd55d7922d32a1c28add63c5 Mon Sep 17 00:00:00 2001
From: Tiago Conte <tiagohconte@gmail.com>
Date: Thu, 23 Feb 2023 11:23:55 -0300
Subject: [PATCH] Implementa forward

---
 compilador.h |  3 ++-
 compilador.l |  6 +++++
 compilador.y | 62 ++++++++++++++++++++++++++++++++++------------------
 3 files changed, 49 insertions(+), 22 deletions(-)

diff --git a/compilador.h b/compilador.h
index e781868..10e82e7 100644
--- a/compilador.h
+++ b/compilador.h
@@ -65,7 +65,8 @@ typedef enum simbolos {
     simb_integer,
     simb_boolean,
     simb_read,
-    simb_write
+    simb_write,
+    simb_forward
 } simbolos;
 
 typedef enum operacoes_t {
diff --git a/compilador.l b/compilador.l
index fee9159..0be2211 100644
--- a/compilador.l
+++ b/compilador.l
@@ -281,6 +281,12 @@ write { simbolo = simb_write;
           return WRITE;
         }
 
+forward { simbolo = simb_forward;
+          strncpy (token, yytext, TAM_TOKEN);
+          IMPRIME(" forward ");
+          return FORWARD;
+        }
+
 {numero} { simbolo = simb_numero;
           strncpy (token, yytext, TAM_TOKEN);
           IMPRIME(" numero  ");
diff --git a/compilador.y b/compilador.y
index da1547d..b4eb22f 100644
--- a/compilador.y
+++ b/compilador.y
@@ -38,7 +38,7 @@ char ident[50];
 %token T_BEGIN T_END VAR NUMERO IDENT ATRIBUICAO
 %token PROCEDURE FUNCTION GOTO LABEL ARRAY OF
 %token IF THEN ELSE WHILE DO INTEGER BOOLEAN
-%token READ WRITE
+%token READ WRITE FORWARD
 
 /* Para funcionar o IF THEN ELSE
    Precedências são crescentes, logo "lower_than_else" < "else" */
@@ -175,25 +175,34 @@ parte_declara_subrotinas:
 declara_proc: PROCEDURE IDENT
             {
                // fprintf(stderr, "Ident: %s\n", token);
-
                char *rotulo;
 
-               stack_push(rotulos, next_rot());
-
                nivelLex++;
 
+               // Adiciona procedimento à tabela de simbolos
+               if (buscaTS(token) == -1) {
+                  stack_push(rotulos, next_rot());
+                  rotulo = stack_item(rotulos, rotulos->top);
+                  insereTS(token, cat_procedimento,
+                     criaAtrProcedimento(rotulo));
+               }
+
+            }
+            param_formais
+            PONTO_E_VIRGULA declara_proc_extra
+;
+
+/* REGRA 12 - extra */
+declara_proc_extra: FORWARD PONTO_E_VIRGULA { nivelLex--; }
+            | {
+               char *rotulo;
+
                // Gera ENPR k com rotulo
                rotulo = stack_item(rotulos, rotulos->top);
                sprintf(comando, "ENPR %d", nivelLex);
                geraCodigo(rotulo, comando);
 
-               // Adiciona procedimento à tabela de simbolos
-               insereTS(token, cat_procedimento,
-                  criaAtrProcedimento(rotulo));
-
-            }
-            param_formais
-            PONTO_E_VIRGULA bloco PONTO_E_VIRGULA
+            } bloco PONTO_E_VIRGULA
             {
                char *rotulo;
 
@@ -220,17 +229,14 @@ declara_func: FUNCTION IDENT
 
                char *rotulo;
 
-               stack_push(rotulos, next_rot());
-
                nivelLex++;
 
-               // Gera ENPR k com rotulo
-               rotulo = stack_item(rotulos, rotulos->top);
-               sprintf(comando, "ENPR %d", nivelLex);
-               geraCodigo(rotulo, comando);
-
-               // Adiciona função à tabela de simbolos
-               insereTS(token, cat_funcao, criaAtrFuncao(rotulo));
+               // Se não existe, adiciona função à tabela de simbolos
+               if (buscaTS(token) == -1) {
+                  stack_push(rotulos, next_rot());
+                  rotulo = stack_item(rotulos, rotulos->top);
+                  insereTS(token, cat_funcao, criaAtrFuncao(rotulo));
+               }
 
             }
             param_formais DOIS_PONTOS tipo
@@ -246,7 +252,20 @@ declara_func: FUNCTION IDENT
                      break;
                }
             }
-            PONTO_E_VIRGULA bloco PONTO_E_VIRGULA
+            PONTO_E_VIRGULA declara_func_extra
+;
+
+/* REGRA 13 - extra */
+declara_func_extra: FORWARD PONTO_E_VIRGULA { nivelLex--; }
+            | {
+               char *rotulo;
+
+               // Gera ENPR k com rotulo
+               rotulo = stack_item(rotulos, rotulos->top);
+               sprintf(comando, "ENPR %d", nivelLex);
+               geraCodigo(rotulo, comando);
+
+            } bloco PONTO_E_VIRGULA
             {
                char *rotulo;
 
@@ -567,6 +586,7 @@ comando_repetitivo: WHILE
 /* REGRA 24 */
 lista_expr:   lista_expr VIRGULA { num_params++; } expr
             | expr
+            |
 ;
 
 /* REGRA 25 */
-- 
GitLab