|
| 1 | +## Sprint 3 (D21–D30) — AST, símbolos e semântica básica |
| 2 | + |
| 3 | +### Núcleo semântico unificado: definir AST (expr/stmt/decl/fun), tabela de símbolos com escopos, checagem/conversão int↔float e mensagens de erro com linha/coluna |
| 4 | + |
| 5 | + - [ ] responsáveis: @Sophiassilva |
| 6 | + - **Entregáveis obrigatórios:** |
| 7 | + - `src/ast.h` / `src/ast.c` com a hierarquia de nós (expressões, comandos, declarações, funções) e utilitários de criação/destruição. |
| 8 | + - `src/symbol_table.h` / `src/symbol_table.c` com pilha de escopos (funções para `enter_scope`, `leave_scope`, `insert_symbol`, `lookup`). |
| 9 | + - Estrutura de `Type` compartilhada para representar `int`, `float`, `bool`, `char`, ponteiros simples e arrays 1D. |
| 10 | + - Funções de checagem/promoção (`type_can_assign`, `promote_numeric`) acionadas pelas ações semânticas do parser. |
| 11 | + - Emissão de erro padrão `Erro [linha:col]: mensagem` com localização do token via `@n` do Bison. |
| 12 | + - **Passos sugeridos:** |
| 13 | + - Definir um `enum AstKind { AST_VAR_DECL, AST_ASSIGN, AST_IF, ... }` e structs específicas por categoria (ex.: `AstExpression`, `AstStatement`). |
| 14 | + - Mapear tokens para tipos internos: ao ver `INT`, criar `TYPE_INT`; ao ver `FLOAT_TYPE`, `TYPE_FLOAT` etc. |
| 15 | + - Guardar no símbolo `Symbol { const char *name; Type *type; int depth; }` a origem (linha/coluna) para diagnósticos. |
| 16 | + - Integrar com o parser: cada regra deve construir a AST correspondente e empilhar símbolos quando entrar em um bloco `{}`. |
| 17 | + - Escrever testes mínimos em `tests/semantic/` que instanciam a Tabela de Símbolos via código C (sem parser) para validar inserções e shadowing. |
| 18 | + - **Exemplos adicionais:** |
| 19 | + - **AST:** Para `if (x > 0) { x = x - 1; }`, gerar `If(cond: Binary(op: GT, left: Id("x"), right: Int(0)), thenBlock: Block{ Assign(Id("x"), Binary(MINUS, Id("x"), Int(1))) }, elseBlock: null)`. |
| 20 | + - **Tabela de símbolos com escopos:** |
| 21 | + | Escopo | Símbolo | Tipo | Profundidade | |
| 22 | + |--------|---------|------|--------------| |
| 23 | + | global | x | int | 0 | |
| 24 | + | if | y | bool | 1 | |
| 25 | + - **Promoção numérica:** `float y = 2 + 3.5;` deve produzir um nó Binário cujo resultado tem `TYPE_FLOAT`, convertendo o `2` para `2.0` automaticamente. |
| 26 | + - **Mensagem de erro rica:** `Erro [5:3]: variável 'z' não declarada; escopo atual possui {x, y}.` |
| 27 | + |
| 28 | +### Suporte sintático essencial: declarações, atribuições, blocos, if/else, while/for, curto-circuito lógico e comparações (==, \!=, \<, \<=, \>, \>=) |
| 29 | + |
| 30 | + - [ ] responsáveis: @marcomarquesdc |
| 31 | + - **Entregáveis obrigatórios:** |
| 32 | + - Regras no `src/parser.y` cobrindo: |
| 33 | + - Declaração de variáveis (com inicialização opcional) e de vetores 1D. |
| 34 | + - Atribuições simples e compostas (ex.: `+=`, se decidirmos suportar, documentar). |
| 35 | + - Blocos `{ ... }` com criação/destruição de escopo. |
| 36 | + - Estruturas de controle `if/else`, `while`, `for (init; cond; step)` e `do ... while`. |
| 37 | + - Operadores lógicos com curto-circuito (`&&`, `||`) e comparações. |
| 38 | + - Ações semânticas que instanciam nós da AST definidos na tarefa anterior. |
| 39 | + - Atualização dos tokens na `src/lexer.l` se novos operadores forem necessários (ex.: `<=`, `>=`, `!=` já existem; avaliar `+=`, `-=` etc.). |
| 40 | + - Casos de teste em `tests/syntax/` validando cada construção (happy path + caso de erro por falta de `;`). |
| 41 | + - **Passos sugeridos:** |
| 42 | + - Planejar a precedência/associatividade completa no Bison, incluindo atribuições à direita. |
| 43 | + - Reutilizar a regra `program` para aceitar múltiplas declarações e funções. |
| 44 | + - Garantir que `for` seja reescrito em AST como um nó com três componentes (init/cond/update) e um corpo `Block`. |
| 45 | + - Incluir ações de `yyerror` informando token esperado, aproveitando localizações. |
| 46 | + - **Exemplo alvo:** além do snippet abaixo, teste `for` com incremento, e `if` aninhados com `&&`/`||` para confirmar curto-circuito. |
| 47 | + ```c |
| 48 | + int i = 0; |
| 49 | + for (; i < 5 && i != 3; i = i + 1) { |
| 50 | + if (i % 2 == 0) { |
| 51 | + puts("par"); |
| 52 | + } else { |
| 53 | + puts("ímpar"); |
| 54 | + } |
| 55 | + } |
| 56 | + ``` |
| 57 | +
|
| 58 | +### Análise Semântica: missão Lua abrangente: variáveis locais, expressões, operadores lógicos, arrays 1D como tabelas, mapeamento de printf/puts, helpers de runtime quando necessário |
| 59 | +
|
| 60 | + - [ ] responsáveis: @Liviarodrigues1 |
| 61 | + - **Entregáveis obrigatórios:** |
| 62 | + - Módulo `src/semantics.c` com passagens sobre a AST para checar tipos, resolver identificadores e anotar cada nó com tipo final. |
| 63 | + - Implementação das regras de promoção (int→float, char→int, bool→int quando permitido) e erros quando a combinação é inválida (`int + string`, `if` com expressão não booleana, etc.). |
| 64 | + - Representação de arrays como vetores Lua (`{}`) incluindo deslocamento +1 no índice. |
| 65 | + - Funções helper em `runtime/printf.lua` ou similar para cobrir `printf`/`puts` e conversões básicas. |
| 66 | + - Relatório de semântica (ex.: `docs/relatorios/semantica_sprint3.md`) com casos validados e conhecidos a resolver. |
| 67 | + - **Passos sugeridos:** |
| 68 | + - Percorrer a AST pós-parsing: primeiro declaração de variáveis/funções, depois corpo. |
| 69 | + - Armazenar em cada nó `AstExpression` os campos `type` e flags (`is_const`, `is_lvalue`). |
| 70 | + - Sempre que gerar Lua, garantir que `&&` e `||` se tornem `and`/`or` e mantenham curto-circuito (uso direto já atende). |
| 71 | + - Para arrays, converter `arr[i]` em `arr[i + 1]` no código gerado. |
| 72 | + - Incluir testes: `tests/semantic/pass/*.c` (sem erros) e `tests/semantic/fail/*.c` (erro esperado com golden file da mensagem). |
| 73 | + - **Exemplos ampliados de tradução C → Lua:** |
| 74 | + - **Arrays 1D:** |
| 75 | + ```c |
| 76 | + int arr[3] = {10, 20, 30}; |
| 77 | + arr[1] = 99; |
| 78 | + ``` |
| 79 | + ↓ |
| 80 | + ```lua |
| 81 | + local arr = {10, 20, 30} |
| 82 | + arr[2] = 99 |
| 83 | + ``` |
| 84 | + - **Curto-circuito com ponteiros simulados:** |
| 85 | + ```c |
| 86 | + if (ptr != NULL && ptr->val > 10) { log(ptr->val); } |
| 87 | + ``` |
| 88 | + ↓ |
| 89 | + ```lua |
| 90 | + if ptr ~= nil and ptr.val > 10 then |
| 91 | + log(ptr.val) |
| 92 | + end |
| 93 | + ``` |
| 94 | + - **Mapeamento de `printf`:** |
| 95 | + ```c |
| 96 | + printf("Valor: %d e %f\n", a, b); |
| 97 | + ``` |
| 98 | + ↓ |
| 99 | + ```lua |
| 100 | + print(string.format("Valor: %d e %f", a, b)) |
| 101 | + ``` |
| 102 | +
|
| 103 | +### Funções completas: traduzir assinaturas e return de C para function Lua, preservar escopos e chamadas |
| 104 | +
|
| 105 | + - [ ] responsáveis: @BeyondMagic |
| 106 | + - **Entregáveis obrigatórios:** |
| 107 | + - Tradução de declarações de função para AST (`AstFunction`) com lista de parâmetros, tipo de retorno e bloco corpo. |
| 108 | + - Geração Lua correspondente em `src/codegen_lua.c` (novo arquivo) ou módulo existente, incluindo: |
| 109 | + - `local function nome(parametros)` para funções não-`main`. |
| 110 | + - Função `main` convertida em wrapper `os.exit((function(args) ... end)(arg))`. |
| 111 | + - Suporte a chamadas (`call`) com coerção de argumentos e verificação de aridade. |
| 112 | + - Atualização da tabela de símbolos para tratar parâmetros como variáveis do primeiro escopo do corpo. |
| 113 | + - **Passos sugeridos:** |
| 114 | + - Durante parsing, capturar lista de parâmetros (`ParamDecl`) e inserir no escopo da função antes de analisar o corpo. |
| 115 | + - Anotar na AST se a função retorna valor; emitir erro se caminho sem `return` em função não-`void`. |
| 116 | + - Implementar geração de `return` Lua com conversão de tipos se necessário (`return (tonumber(expr))` nos casos obrigatórios). |
| 117 | + - Cobrir chamadas aninhadas e recursão, garantindo que símbolos sejam resolvidos. |
| 118 | + - **Exemplo de tradução C → Lua (com parâmetros e retorno):** |
| 119 | + ```c |
| 120 | + float media(float a, float b) { |
| 121 | + return (a + b) / 2; |
| 122 | + } |
| 123 | +
|
| 124 | + int main() { |
| 125 | + float resultado = media(5, 7); |
| 126 | + return 0; |
| 127 | + } |
| 128 | + ``` |
| 129 | + ↓ |
| 130 | + ```lua |
| 131 | + local function media(a, b) |
| 132 | + return (a + b) / 2 |
| 133 | + end |
| 134 | + |
| 135 | + os.exit((function(args) |
| 136 | + local resultado = media(5, 7) |
| 137 | + return 0 |
| 138 | + end)(arg)) |
| 139 | + ``` |
| 140 | + |
| 141 | +### Garantia de qualidade: testes de semântica (erros de escopo/tipo), golden files de erro, pipeline end-to-end (C → Lua → execução), linemap/diagnóstico e atualização de docs/demo |
| 142 | + |
| 143 | + - [ ] responsáveis: @andrelopesdesousa |
| 144 | + - **Entregáveis obrigatórios:** |
| 145 | + - Estrutura de testes automatizados: |
| 146 | + - `tests/semantic/pass/*.c` + `.lua` esperados. |
| 147 | + - `tests/semantic/fail/*.c` + `.err` com mensagens exatas. |
| 148 | + - Script `tests/run_semantic_tests.sh` usando o binário `c2lua` + Lua 5.4 para validar fim-a-fim. |
| 149 | + - Relato de cobertura: planilha simples ou markdown indicando quais operadores/constructos possuem testes. |
| 150 | + - Documentação atualizada (`docs/Guia - Projeto de um compilador.md`) adicionando seção "Como rodar a suíte semântica". |
| 151 | + - Demonstração (gif curto ou log) anexado em `docs/demo/` mostrando o pipeline `C -> Lua -> execução`. |
| 152 | + - **Passos sugeridos:** |
| 153 | + - Reaproveitar `tests/run_expr_tests.sh` como base, extraindo funções comuns em `tests/lib/test_utils.sh`. |
| 154 | + - Incluir check que compara saída de erro com golden file removendo diferenças irrelevantes (ex.: caminhos absolutos). |
| 155 | + - Integrar no CI local (target `make test-semantic`) chamando o script de testes + `luac -p` no Lua gerado para validar sintaxe. |
| 156 | + - Criar casos específicos: variável fora de escopo, retorno faltante, tipo inesperado em `while`, indexação fora de array (detectar ou documentar se não suportado). |
| 157 | + - **Exemplos de testes:** |
| 158 | + - **Tipo inválido:** `int x = "hello";` → erro `Erro [1:9]: atribuição int <- string não permitida`. |
| 159 | + - **Escopo:** `int x = 1; { int y = 2; } y = 3;` → erro `Erro [1:26]: símbolo 'y' não encontrado`. |
| 160 | + - **Pipeline End-to-End:** |
| 161 | + 1. `./c2lua tests/pass/test_sum.c > build/out.lua` |
| 162 | + 2. `lua build/out.lua` produz `4`. |
| 163 | + 3. Script valida stdout e imprime `PASS test_sum`. |
| 164 | + |
| 165 | +## Critérios de pronto por fase |
| 166 | + |
| 167 | + - Léxico: todos tokens do MVP reconhecidos; sem vazamentos de memória. |
| 168 | + - Sintático: AST correta para expressões e comandos principais. |
| 169 | + - Semântico: checagens básicas de tipos/escopos; mensagens com linha/coluna. |
| 170 | + - Geração Lua: programas do MVP executam em Lua com mesmo resultado. |
| 171 | + - Qualidade: testes cobrindo happy path + erros; build reprodutível. |
| 172 | + |
| 173 | +## Referências rápidas |
| 174 | + |
| 175 | + - Flex: padrões, yytext, yylex, yylval. |
| 176 | + - Bison: gramática, precedência, $$/$1, yyparse, yyerror. |
| 177 | + - Lua 5.x: escopo local, funções, tabelas, operadores, print. |
| 178 | + |
| 179 | +Observação: atualize os checkboxes conforme avança e preencha os responsáveis inline. |
0 commit comments