refactoring and reducing complexity

This commit is contained in:
bQUARKz 2026-03-10 09:06:44 +00:00
parent b7c99eec42
commit 1c38b19772
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
15 changed files with 788 additions and 61 deletions

View File

@ -155,3 +155,23 @@ Foco: remover definitivamente `moduleKey` textual do contrato estrutural FE->BE,
5. `PR-09.5-hard-gates-no-modulekey-regression-and-migration-cleanup.md`
6. `PR-09.6-isa-intrinsic-registry-single-source-artifact.md`
7. `PR-09.7-compiler-normalization-to-isa-registry-artifact.md`
### Onda O10 - Parser Maintainability Refactor (No Functional Change)
Foco: reduzir complexidade estrutural de `PbsParser` sem alterar gramatica, AST, spans ou contrato de diagnosticos observavel.
1. `PR-10.1-pbs-parser-shared-context-and-safe-delegation.md`
2. `PR-10.2-pbs-parser-attribute-and-type-subparsers.md`
3. `PR-10.3-pbs-parser-top-level-declaration-decomposition.md`
4. `PR-10.4-pbs-parser-block-and-statement-decomposition.md`
5. `PR-10.5-pbs-parser-recovery-utilities-and-regression-hardening.md`
### Onda O11 - Expression Parser Maintainability Refactor (No Functional Change)
Foco: reduzir complexidade estrutural de `PbsExprParser` sem alterar precedence, AST, spans, recovery ou diagnosticos observaveis.
1. `PR-11.1-pbs-expr-parser-shared-context-and-precedence-spine.md`
2. `PR-11.2-pbs-expr-parser-control-flow-subparsers.md`
3. `PR-11.3-pbs-expr-parser-postfix-primary-and-construction-decomposition.md`
4. `PR-11.4-pbs-expr-parser-literals-patterns-and-shared-token-utilities.md`
5. `PR-11.5-pbs-expr-parser-regression-hardening-and-final-cleanup.md`

View File

@ -0,0 +1,69 @@
# PR-10.1 - PBS Parser Shared Context and Safe Delegation
## Briefing
`PbsParser` concentra estado compartilhado (`cursor`, `diagnostics`, `fileId`, `parseMode`, `loopDepth`) e responsabilidades de parsing em uma unica classe.
Esta PR introduz uma fundacao estrutural para decomposicao, sem alterar comportamento: um contexto compartilhado e pontos de delegacao seguros, mantendo `PbsParser` como fachada publica.
## Motivation
### Dor atual que esta PR resolve
1. Extracoes futuras dependem de copiar estado ou expor detalhes internos do parser.
2. O acoplamento entre navegação, diagnostico e parse impede quebrar a classe sem risco alto.
3. A refatoracao fica mais segura se a infraestrutura de compartilhamento vier antes da movimentacao de logica.
## Target
Estabelecer a base de refactor sem mudar funcionalidade:
1. Introduzir um contexto compartilhado para parser.
2. Encapsular helpers comuns de span/report/consume no contexto ou utilitarios proximos.
3. Permitir delegacao gradual para subparsers mantendo `PbsParser.parse(...)` como API unica.
## Dependencies
Nenhuma.
## Scope
1. Criar `ParserContext` ou equivalente com acesso a `cursor`, `diagnostics`, `fileId`, `parseMode` e `loopDepth`.
2. Mover helpers estruturais triviais para o contexto onde isso nao altere semantica.
3. Adaptar `PbsExprParser` bootstrap para consumir o mesmo contexto, ou uma visao compatível, sem mudar seu comportamento.
## Non-Goals
1. Nao alterar gramatica PBS.
2. Nao mover ainda parsing de tipos, atributos, blocos ou declaracoes para classes separadas.
3. Nao alterar mensagens, codigos de erro ou spans.
## Method
### O que deve ser feito explicitamente
1. Introduzir um objeto de contexto pequeno e explicito.
2. Manter `PbsParser` como orquestrador/fachada durante toda a PR.
3. Preservar o contrato de `parse(...)` e a ordem de consumo de tokens.
4. Validar que a nova camada e puramente estrutural.
## Acceptance Criteria
1. `PbsParser` continua sendo o unico entrypoint publico de parse.
2. Nenhum teste de parser, semantica ou frontend muda comportamento esperado.
3. Nao ha alteracao observavel em AST, spans ou diagnosticos.
4. A PR reduz acoplamento e prepara extracoes futuras sem mover regras complexas ainda.
## Tests
1. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsParserTest*`
2. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsExprParserTest*`
3. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test`
## Affected Documents
1. Nenhum documento normativo.
## Open Questions
1. O `loopDepth` deve viver no contexto mutavel compartilhado ou em um helper especializado de block parsing? Esta PR pode manter no contexto; a decisao final pode vir na `PR-10.4`.

View File

@ -0,0 +1,70 @@
# PR-10.2 - PBS Parser Attribute and Type Subparsers
## Briefing
`PbsParser` ainda centraliza parsing de atributos, `typeRef` e `returnSpec`, que sao superficies coesas e amplamente reutilizadas.
Esta PR extrai essas responsabilidades para subparsers dedicados, sem alterar sintaxe aceita, AST produzido ou diagnosticos.
## Motivation
### Dor atual que esta PR resolve
1. `PbsParser` mistura topo de arquivo, declaracoes, blocos, atributos e tipos.
2. `parseTypeRef`, `parseAttribute*` e `parseCallableReturnSpec` sao hotspots claros de complexidade e reuso.
3. Sem extrair essa camada, as PRs seguintes continuam dependendo de uma classe central grande demais.
## Target
Separar parsing de tipos e atributos em colaboradores dedicados:
1. `PbsAttributeParser` ou equivalente.
2. `PbsTypeParser` ou equivalente.
3. Delegacao explicita a partir de `PbsParser`.
## Dependencies
Prerequisito direto:
1. `PR-10.1`
## Scope
1. Extrair `parseAttributeList`, `parseAttribute`, `parseAttributeArguments`, `parseAttributeArgument`, `parseAttributeValue`.
2. Extrair `parseTypeRef`, `parseNamedTupleTypeFields`, `parseCallableReturnSpec`, `parseReturnSpecFromMarker`, `isTypeStart`.
3. Preservar integralmente `PbsAst` e `ParseErrors`.
## Non-Goals
1. Nao alterar regras de atributos em modos `ORDINARY` e `INTERFACE_MODULE`.
2. Nao alterar aridade de named tuple.
3. Nao alterar recuperacao de erro alem do necessario para manter equivalencia.
## Method
### O que deve ser feito explicitamente
1. Mover parsing de atributos e tipos para classes pequenas, focadas e package-private.
2. Reusar o contexto compartilhado introduzido na PR anterior.
3. Manter `PbsParser` apenas como delegador nessas superficies.
4. Adicionar regressao para spans e diagnosticos de tipos/atributos se ainda nao houver cobertura suficiente.
## Acceptance Criteria
1. `PbsParser` deixa de implementar diretamente a maior parte do parsing de atributos e tipos.
2. AST e diagnosticos dessas superficies permanecem equivalentes.
3. A cobertura existente de parser continua verde sem mudancas semanticas.
## Tests
1. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsParserTest*`
2. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsExprParserTest*`
3. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsInterfaceModuleSemanticsTest*`
## Affected Documents
1. Nenhum documento normativo.
## Open Questions
1. Se `returnSpec` deve ficar no parser de tipos ou em um parser de callable surface. A recomendacao desta PR e manter em `PbsTypeParser`, porque o contrato de retorno depende diretamente de `typeRef`.

View File

@ -0,0 +1,73 @@
# PR-10.3 - PBS Parser Top-Level Declaration Decomposition
## Briefing
O maior concentrador de branching restante em `PbsParser` e a montagem de topo de arquivo e o dispatch de `declare ...`.
Esta PR extrai o parsing de declaracoes top-level e de corpos declarativos para colaboradores especificos, mantendo a mesma gramatica e o mesmo comportamento observavel.
## Motivation
### Dor atual que esta PR resolve
1. `parseFile` e `parseDeclareTopDecl` acumulam roteamento de muitas formas de declaracao.
2. Declaracoes como `host`, `builtin type`, `struct`, `contract`, `service`, `enum` e `implements` convivem no mesmo arquivo e elevam acoplamento.
3. Essa parte do parser muda com frequencia e hoje tem custo alto de manutencao.
## Target
Separar a camada de declaracoes top-level:
1. parsing de imports,
2. dispatch de `declare`,
3. parsing de corpos declarativos,
4. roteamento por `ParseMode`.
## Dependencies
Prerequisitos diretos:
1. `PR-10.1`
2. `PR-10.2`
## Scope
1. Extrair `parseFile` em conjunto com o dispatch de topo para um colaborador dedicado.
2. Extrair `parseDeclareTopDecl` e parsers correlatos (`host`, `builtin type`, `struct`, `contract`, `service`, `error`, `enum`, `callback`, `const`, `implements`).
3. Preservar o comportamento atual de atributos permitidos/proibidos por tipo de declaracao.
## Non-Goals
1. Nao alterar a ordem de imports/declarations no AST.
2. Nao alterar as regras de `INTERFACE_MODULE`.
3. Nao reescrever `PbsExprParser`.
## Method
### O que deve ser feito explicitamente
1. Criar um `PbsTopLevelParser` e um `PbsDeclarationParser`, ou divisao equivalente.
2. Manter em `PbsParser` apenas a montagem final da fachada e o fio de chamada principal.
3. Extrair por familias coesas de declaracao, evitando uma nova classe monolitica.
4. Preservar sincronia/recovery de topo no mesmo fluxo observavel.
## Acceptance Criteria
1. `parseFile` e `parseDeclareTopDecl` deixam de concentrar o dispatch completo de todas as declaracoes.
2. O parse de topo continua deterministico e equivalente ao estado anterior.
3. Testes de parser e frontend continuam verdes sem necessidade de atualizar fixtures por mudanca funcional.
## Tests
1. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsParserTest*`
2. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsBarrelParserTest*`
3. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsInterfaceModuleSemanticsTest*`
4. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test`
## Affected Documents
1. Nenhum documento normativo.
## Open Questions
1. `implements` deve ficar junto de declaracoes top-level gerais ou em um parser especializado de contract/service surfaces? A recomendacao e mantê-lo no parser top-level por depender fortemente do roteamento de arquivo.

View File

@ -0,0 +1,74 @@
# PR-10.4 - PBS Parser Block and Statement Decomposition
## Briefing
Depois de extrair tipos/atributos e declaracoes top-level, o maior hotspot restante de `PbsParser` passa a ser parsing de blocos e statements.
Esta PR separa `block`, `statement`, `assignment`, `loop` e controle de fluxo em um parser dedicado, sem alterar a funcionalidade.
## Motivation
### Dor atual que esta PR resolve
1. `parseBlock`, `parseStatement`, `parseIfStatement`, `parseForStatement` e correlatos mantem alta complexidade e forte acoplamento com `loopDepth`.
2. A mistura de statement parsing com helpers de token/erro dificulta evolucao e leitura.
3. O parser de blocos e o ponto mais sensivel para regressao e precisa de uma fronteira estrutural clara.
## Target
Extrair a superficie de blocos e statements para um colaborador dedicado:
1. blocos,
2. statements estruturados,
3. assignment detection,
4. controle de `loopDepth`.
## Dependencies
Prerequisitos diretos:
1. `PR-10.1`
2. `PR-10.2`
3. `PR-10.3`
## Scope
1. Extrair `parseBlock`, `parseStatement`, `parseLetStatement`, `parseAssignStatement`, `parseLValue`.
2. Extrair `parseIfStatement`, `parseForStatement`, `parseWhileStatement`, `parseBreakStatement`, `parseContinueStatement`, `parseReturnStatement`.
3. Extrair `isAssignmentStatementStart` e helpers locais associados.
## Non-Goals
1. Nao alterar regras de tail expression.
2. Nao alterar precedence de expressoes.
3. Nao alterar as mensagens atuais de erro para loop control e assignment targets.
## Method
### O que deve ser feito explicitamente
1. Introduzir um `PbsBlockParser` ou equivalente.
2. Encapsular `loopDepth` dentro do contexto compartilhado ou de uma API pequena de entrada/saida de loop.
3. Reutilizar `PbsExprParser` como dependencia, sem alterar seu contrato.
4. Preservar spans e forma de recovery dentro de blocos.
## Acceptance Criteria
1. `PbsParser` deixa de conter a maior parte do parsing de blocos e statements.
2. `loopDepth` continua correto para `break` e `continue`.
3. Nenhum teste de parser, semantica de flow ou lowering sofre alteracao funcional.
## Tests
1. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsParserStatementsTest*`
2. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsSemanticsControlFlowTest*`
3. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsSemanticsFallthroughTest*`
4. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test`
## Affected Documents
1. Nenhum documento normativo.
## Open Questions
1. `isAssignmentStatementStart` deve permanecer no parser de bloco ou virar helper de cursor/lookahead. A recomendacao e mantê-lo no parser de bloco nesta PR e avaliar extração posterior apenas se necessário.

View File

@ -0,0 +1,80 @@
# PR-10.5 - PBS Parser Recovery Utilities and Regression Hardening
## Briefing
As PRs anteriores reduzem a complexidade estrutural de `PbsParser`. Esta PR fecha a trilha com consolidacao de recovery/utilitarios e endurecimento de regressao, ainda sem alterar funcionalidade.
O objetivo e evitar que a decomposicao introduza pequenas divergencias em diagnosticos, spans ou pontos de reinicio.
## Motivation
### Dor atual que esta PR resolve
1. Recovery e helpers de consumo sao sensiveis e podem ficar duplicados apos a extracao.
2. Sem cobertura adicional, uma refatoracao estrutural grande pode preservar testes principais e ainda mudar detalhes de parser.
3. O parser precisa terminar menor, mas tambem com fronteiras de manutencao claras.
## Target
Consolidar a etapa final do refactor:
1. recovery de topo e de atributos,
2. helpers de consumo/report,
3. regressao de spans/diagnosticos,
4. limpeza final de `PbsParser`.
## Dependencies
Prerequisitos diretos:
1. `PR-10.1`
2. `PR-10.2`
3. `PR-10.3`
4. `PR-10.4`
## Scope
1. Consolidar `consume`, `consumeForToken`, `consumeDeclarationTerminator`, `consumeBalancedBraces`, `synchronizeTopLevel` e recovery de atributo em utilitarios coesos.
2. Remover duplicacao residual entre subparsers.
3. Adicionar ou endurecer testes de regressao para:
- spans,
- erros esperados,
- recovery em topo e em bloco,
- modos `ORDINARY` e `INTERFACE_MODULE`.
## Non-Goals
1. Nao alterar taxonomia de `ParseErrors`.
2. Nao introduzir novas construcoes sintaticas.
3. Nao reescrever o lexer ou `PbsExprParser`.
## Method
### O que deve ser feito explicitamente
1. Fazer uma passada final de consolidacao estrutural.
2. Eliminar helpers obsoletos ou duplicados apos as extracoes.
3. Verificar equivalencia observavel com foco em spans e recovery.
4. Encerrar a trilha com `PbsParser` como fachada pequena e clara.
## Acceptance Criteria
1. `PbsParser` fica restrito a composicao/orquestracao e nao volta a concentrar logica de parse pesado.
2. Recovery e consumo de token ficam centralizados e sem duplicacao relevante.
3. Suite do frontend PBS passa integralmente.
4. Nao ha mudanca funcional observavel em parse, AST ou diagnosticos.
## Tests
1. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsParserTest*`
2. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsParserStatementsTest*`
3. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsExprParserTest*`
4. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test`
## Affected Documents
1. Nenhum documento normativo.
## Open Questions
1. Nenhuma de arquitetura. A partir desta PR, qualquer mudanca adicional deve ser tratada como evolucao funcional separada, nao como parte do refactor estrutural.

View File

@ -0,0 +1,68 @@
# PR-11.1 - PBS Expr Parser Shared Context and Precedence Spine
## Briefing
`PbsExprParser` hoje concentra estado compartilhado, helpers basicos e toda a espinha de precedence em uma unica classe.
Esta PR introduz a fundacao estrutural para decompor o parser de expressoes sem alterar comportamento: contexto compartilhado, helpers comuns e uma organizacao mais clara da cadeia de precedence.
## Motivation
### Dor atual que esta PR resolve
1. Extracoes futuras dependem de duplicar acesso a `cursor`, `diagnostics`, `fileId` e `blockParserDelegate`.
2. A cadeia de precedence existe, mas toda a infraestrutura esta acoplada a uma unica classe.
3. Refatorar primeiro a fundacao reduz risco antes de mover control-flow e postfix/primary.
## Target
Estabelecer uma base segura para o refactor de `PbsExprParser`:
1. contexto compartilhado,
2. helpers de span/report/consume reutilizaveis,
3. espinha de precedence claramente separada do restante.
## Dependencies
Nenhuma.
## Scope
1. Introduzir `ExprParserContext` ou equivalente.
2. Encapsular `cursor`, `diagnostics`, `fileId` e `blockParserDelegate` nessa camada.
3. Reorganizar a espinha de precedence (`parseExpression`, `parseApply`, `parseOr`, `parseAnd`, `parseEquality`, `parseComparison`, `parseAs`, `parseTerm`, `parseFactor`, `parseUnary`) sem mudar a ordem semantica.
## Non-Goals
1. Nao alterar associatividade ou precedence.
2. Nao mover ainda parsing de `if/switch/handle`.
3. Nao alterar `PbsParser` nem `PbsTokenCursor`.
## Method
### O que deve ser feito explicitamente
1. Criar um contexto compartilhado pequeno e explicito.
2. Manter `PbsExprParser` como entrypoint package-private.
3. Preservar a ordem atual de chamadas na chain de precedence.
4. Validar que esta PR e puramente estrutural.
## Acceptance Criteria
1. `PbsExprParser` continua com o mesmo contrato de entrada/saida.
2. Precedence e associatividade permanecem equivalentes.
3. Nao ha mudanca observavel em AST, spans ou diagnosticos de expressoes.
## Tests
1. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsExprParserTest*`
2. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsParserTest*`
3. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test`
## Affected Documents
1. Nenhum documento normativo.
## Open Questions
1. `blockParserDelegate` deve continuar como callback simples ou migrar para interface mais rica de surface parsing? Nesta PR, manter callback simples minimiza risco.

View File

@ -0,0 +1,72 @@
# PR-11.2 - PBS Expr Parser Control-Flow Subparsers
## Briefing
As formas de expressao com maior branching em `PbsExprParser` sao `if`, `switch`, `handle` e `else`.
Esta PR extrai essas construcoes para subparsers dedicados, mantendo a mesma sintaxe, mesmos diagnosticos e o mesmo AST.
## Motivation
### Dor atual que esta PR resolve
1. `if/switch/handle` compartilham recovery, parsing de blocos e recursion, elevando bastante a complexidade local.
2. Essas formas sao semanticamente coesas e podem viver fora do parser principal de precedence.
3. Sem essa extracao, `PbsExprParser` continua grande mesmo apos separar a fundacao.
## Target
Separar parsing de expressoes de controle de fluxo:
1. `handle`,
2. `else`,
3. `if expression`,
4. `switch expression`.
## Dependencies
Prerequisito direto:
1. `PR-11.1`
## Scope
1. Extrair `parseHandle`, `parseHandlePattern`, `parseElse`, `parseIfExpression`, `parseIfExpressionFromToken`, `parseSwitchExpression`, `parseSwitchPattern`.
2. Preservar uso de `parseSurfaceBlock` para blocos de expressao.
3. Manter exatamente a precedence atual dessas superficies.
## Non-Goals
1. Nao alterar a regra de `if expression` exigir `else`.
2. Nao alterar curingas de `switch`.
3. Nao alterar formatos aceitos de `handle` e remapeamento de erro.
## Method
### O que deve ser feito explicitamente
1. Introduzir subparsers pequenos por familia de construcao.
2. Reusar o contexto compartilhado da PR anterior.
3. Garantir que `parseExpression()` continue entrando pela mesma superficie sintatica.
4. Proteger a equivalencia com testes focados em control-flow expressions.
## Acceptance Criteria
1. A logica de `if/switch/handle/else` nao fica mais centralizada em `PbsExprParser`.
2. ASTs gerados para essas construcoes permanecem equivalentes.
3. Diagnosticos de formas invalidas continuam com o mesmo contrato observavel.
## Tests
1. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsExprParserTest*`
2. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsParserStatementsTest*`
3. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsSemanticsResultFlowRulesTest*`
4. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test`
## Affected Documents
1. Nenhum documento normativo.
## Open Questions
1. `else` deve viver junto do control-flow parser ou continuar na espinha de precedence. A recomendacao e movê-lo junto porque a associatividade e as mensagens de erro fazem parte do mesmo cluster conceitual.

View File

@ -0,0 +1,74 @@
# PR-11.3 - PBS Expr Parser Postfix, Primary and Construction Decomposition
## Briefing
O segundo grande concentrador de complexidade em `PbsExprParser` esta nas superficies de `postfix` e `primary`: chamadas, membros, propagate, tuplas, blocos, `new`, `bind`, `some/ok/err`.
Esta PR separa essas familias em colaboradores menores, sem alterar a funcionalidade.
## Motivation
### Dor atual que esta PR resolve
1. `parsePostfix`, `parsePrimary` e `parseParenthesizedPrimary` misturam muitas formas sintaticas distintas.
2. Tuple literals, grouped expressions e construction surfaces compartilham lookahead delicado.
3. A manutencao dessas regras num unico metodo torna alto o custo de qualquer evolucao futura.
## Target
Separar parsing de superficies primarias e postfix:
1. postfix chaining,
2. primary literals/identifiers/blocks,
3. tuple/group handling,
4. construction/result surfaces (`new`, `bind`, `some`, `ok`, `err`).
## Dependencies
Prerequisitos diretos:
1. `PR-11.1`
2. `PR-11.2`
## Scope
1. Extrair `parsePostfix`.
2. Extrair `parsePrimary`, `parseParenthesizedPrimary`, `parseTupleItems`, `parseTupleItem`.
3. Extrair `parseNewExpression`, `parseBindExpression`, `parseSomeExpression`, `parseOkExpression`, `parseErrExpression`.
4. Preservar recovery atual para `?`, tuple malformed e parens.
## Non-Goals
1. Nao alterar a aridade de tuple literal.
2. Nao alterar mixed labeled/unlabeled tuple validation.
3. Nao alterar o formato aceito de `new Vec.zero(...)` e `bind(ctx, fn)`.
## Method
### O que deve ser feito explicitamente
1. Introduzir subparsers por familia sintatica em vez de criar um novo monolito.
2. Manter a ordem atual de postfix chaining.
3. Preservar lookahead de tuple/group exatamente como hoje.
4. Reforcar testes de tupla, construction e propagate operator invalido.
## Acceptance Criteria
1. `parsePostfix` e `parsePrimary` deixam de concentrar todas as superficies primarias.
2. Tuplas, grupos, constructions e postfix chains continuam equivalentes.
3. Nao ha mudanca funcional em AST, spans ou diagnosticos.
## Tests
1. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsExprParserTest*`
2. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsParserTest*`
3. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsSemanticsOptionalResultTest*`
4. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsSemanticsApplyResolutionTest*`
## Affected Documents
1. Nenhum documento normativo.
## Open Questions
1. O parsing de tuple/group deve ficar junto de primary ou em helper especializado de parenthesized surfaces. A recomendacao e extrair para helper especializado, porque esse e o trecho com lookahead mais sensivel.

View File

@ -0,0 +1,73 @@
# PR-11.4 - PBS Expr Parser Literals, Patterns and Shared Token Utilities
## Briefing
Depois de extrair control-flow e primary/postfix, restam em `PbsExprParser` alguns clusters menores mas sensiveis: parsing de literais/padroes, `error path`, consumo de tokens e utilitarios de parse numerico/string.
Esta PR consolida esses pontos em utilitarios dedicados, ainda sem mudanca funcional.
## Motivation
### Dor atual que esta PR resolve
1. Parsing de literal aparece em mais de um lugar (`primary` e switch pattern).
2. `error path`, `consumeMemberName`, `parseLong/Int/DoubleOrDefault` e `unescapeString` sao infra compartilhada e hoje permanecem acoplados ao parser principal.
3. Sem consolidar essa base, o parser termina menor, mas ainda com detalhes mecanicos espalhados.
## Target
Extrair infra compartilhada de expressao:
1. parsing de literais,
2. parsing de `error path`,
3. parsing de patterns simples,
4. token utilities e decode helpers.
## Dependencies
Prerequisitos diretos:
1. `PR-11.1`
2. `PR-11.2`
3. `PR-11.3`
## Scope
1. Extrair `parseLiteralPatternExpression`, `parseErrorPath`, `parseHandlePattern` e helpers correlatos.
2. Consolidar `consume`, `consumeMemberName`, `span`, `report`.
3. Consolidar `parseLongOrDefault`, `parseIntOrDefault`, `parseDoubleOrDefault`, `unescapeString`.
## Non-Goals
1. Nao alterar as regras de literal recovery.
2. Nao alterar o decode de strings.
3. Nao alterar a estrutura de `PbsAst.ErrorPath`.
## Method
### O que deve ser feito explicitamente
1. Reunir parsing de literal/pattern em componente reutilizavel.
2. Mover utilitarios mecanicos para helpers claros e pequenos.
3. Garantir que toda chamada mantenha a mesma atribuicao de spans e diagnosticos.
4. Evitar criar uma util-class genérica demais; manter helpers focados no dominio de expression parsing.
## Acceptance Criteria
1. `PbsExprParser` deixa de concentrar parsing repetido de literais/padroes e utilitarios basicos.
2. Parsing de strings, numeros e `error path` permanece equivalente.
3. A suite de parser continua verde sem atualizar comportamento esperado.
## Tests
1. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsExprParserTest*`
2. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsParserTest*`
3. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsSemanticsDeclarationsTest*`
## Affected Documents
1. Nenhum documento normativo.
## Open Questions
1. Nenhuma de arquitetura. Esta PR e de consolidacao local.

View File

@ -0,0 +1,75 @@
# PR-11.5 - PBS Expr Parser Regression Hardening and Final Cleanup
## Briefing
As PRs anteriores reduzem a complexidade estrutural de `PbsExprParser`. Esta PR fecha a trilha com limpeza final, eliminacao de duplicacao residual e endurecimento de regressao, sem alterar funcionalidade.
## Motivation
### Dor atual que esta PR resolve
1. Refactors estruturais em parser de expressao podem mudar detalhes finos sem quebrar imediatamente todos os testes.
2. Ao final da decomposicao, costuma restar duplicacao pequena e helpers obsoletos.
3. O fechamento da trilha precisa garantir equivalencia observavel e uma fachada final pequena.
## Target
Concluir a trilha de refactor do parser de expressoes:
1. limpeza estrutural final,
2. consolidacao dos helpers remanescentes,
3. cobertura de regressao para precedence, postfix, tuples e control-flow expressions.
## Dependencies
Prerequisitos diretos:
1. `PR-11.1`
2. `PR-11.2`
3. `PR-11.3`
4. `PR-11.4`
## Scope
1. Remover codigo duplicado ou caminhos obsoletos apos as extracoes.
2. Garantir que `PbsExprParser` fique reduzido a composicao/orquestracao.
3. Expandir regressao quando necessario para spans, diagnosticos e precedence.
## Non-Goals
1. Nao alterar gramatica de expressoes.
2. Nao introduzir novas formas sintaticas.
3. Nao alterar `PbsAst` ou `ParseErrors`.
## Method
### O que deve ser feito explicitamente
1. Fazer uma passada final de consolidacao.
2. Verificar equivalencia com foco em:
- precedence,
- associatividade,
- tuple/group lookahead,
- control-flow expression recovery.
3. Encerrar a trilha com um `PbsExprParser` pequeno, claro e estavel.
## Acceptance Criteria
1. `PbsExprParser` termina como fachada/orquestrador, nao como concentrador de todas as regras.
2. Nao ha mudanca funcional observavel em AST, spans ou diagnosticos.
3. Suite do frontend PBS passa integralmente.
## Tests
1. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsExprParserTest*`
2. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsParserTest*`
3. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test --tests *PbsParserStatementsTest*`
4. `:prometeu-compiler:frontends:prometeu-frontend-pbs:test`
## Affected Documents
1. Nenhum documento normativo.
## Open Questions
1. Nenhuma. A partir desta PR, qualquer ajuste restante deve ser tratado como mudanca funcional separada.

View File

@ -233,7 +233,7 @@ public final class PbsReservedMetadataExtractor {
return normalizedTypeName + "." + normalizedIntrinsicName;
}
private String typeSurfaceKey(final PbsAst.TypeRef typeRef) {
public static String typeSurfaceKey(final PbsAst.TypeRef typeRef) {
if (typeRef == null) {
return "unit";
}

View File

@ -5,8 +5,8 @@ import p.studio.compiler.source.Span;
import p.studio.compiler.source.diagnostics.DiagnosticSink;
import p.studio.compiler.source.diagnostics.RelatedSpan;
import p.studio.compiler.source.diagnostics.Severity;
import p.studio.compiler.source.identifiers.FileId;
import p.studio.compiler.source.identifiers.CallableShapeId;
import p.studio.compiler.source.identifiers.FileId;
import p.studio.compiler.source.identifiers.NameId;
import p.studio.compiler.source.identifiers.TypeSurfaceId;
import p.studio.compiler.source.tables.CallableShapeTable;
@ -14,12 +14,9 @@ import p.studio.compiler.source.tables.NameTable;
import p.studio.compiler.source.tables.TypeSurfaceTable;
import p.studio.utilities.structures.ReadOnlyList;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import static p.studio.compiler.pbs.PbsReservedMetadataExtractor.typeSurfaceKey;
public final class PbsModuleVisibilityValidator {
@ -91,23 +88,26 @@ public final class PbsModuleVisibilityValidator {
final Map<FunctionSymbolKey, Span> seenFunctionEntries = new HashMap<>();
for (final var item : barrel.ast().items()) {
if (item instanceof PbsAst.BarrelFunctionItem functionItem) {
if (item instanceof PbsAst.BarrelFunctionItem(
PbsAst.Visibility visibility, String name, ReadOnlyList<PbsAst.TypeRef> parameterTypes,
PbsAst.ReturnKind returnKind, PbsAst.TypeRef returnType, PbsAst.TypeRef resultErrorType, Span span
)) {
final var functionKey = functionKey(
functionItem.name(),
functionItem.parameterTypes().asList(),
functionItem.returnKind(),
functionItem.returnType(),
functionItem.resultErrorType(),
name,
parameterTypes.asList(),
returnKind,
returnType,
resultErrorType,
nameTable,
signatureInterning);
final var firstFunctionEntry = seenFunctionEntries.putIfAbsent(functionKey, functionItem.span());
final var firstFunctionEntry = seenFunctionEntries.putIfAbsent(functionKey, span);
if (firstFunctionEntry != null) {
p.studio.compiler.source.diagnostics.Diagnostics.error(diagnostics,
PbsLinkErrors.E_LINK_DUPLICATE_BARREL_ENTRY.name(),
"Duplicate barrel function entry '%s' in module %s".formatted(
functionItem.name(),
name,
displayModule(module.coordinates())),
functionItem.span(),
span,
List.of(new RelatedSpan("First barrel function entry is here", firstFunctionEntry)));
continue;
}
@ -117,23 +117,23 @@ public final class PbsModuleVisibilityValidator {
p.studio.compiler.source.diagnostics.Diagnostics.error(diagnostics,
PbsLinkErrors.E_LINK_UNRESOLVED_BARREL_ENTRY.name(),
"Barrel function entry '%s' in module %s does not resolve to a declaration".formatted(
functionItem.name(),
name,
displayModule(module.coordinates())),
functionItem.span());
span);
continue;
}
if (matches.size() > 1) {
p.studio.compiler.source.diagnostics.Diagnostics.error(diagnostics,
PbsLinkErrors.E_LINK_AMBIGUOUS_BARREL_ENTRY.name(),
"Barrel function entry '%s' in module %s resolves ambiguously".formatted(
functionItem.name(),
name,
displayModule(module.coordinates())),
functionItem.span(),
span,
List.of(new RelatedSpan("One matching function declaration is here", matches.getFirst())));
continue;
}
if (functionItem.visibility() == PbsAst.Visibility.PUB) {
if (visibility == PbsAst.Visibility.PUB) {
exports.publicNameIds.add(functionKey.nameId());
}
continue;
@ -337,24 +337,6 @@ public final class PbsModuleVisibilityValidator {
};
}
private String typeSurfaceKey(final PbsAst.TypeRef typeRef) {
if (typeRef == null) {
return "unit";
}
return switch (typeRef.kind()) {
case SIMPLE -> "simple:" + typeRef.name();
case SELF -> "self";
case OPTIONAL -> "optional(" + typeSurfaceKey(typeRef.inner()) + ")";
case UNIT -> "unit";
case GROUP -> "group(" + typeSurfaceKey(typeRef.inner()) + ")";
case NAMED_TUPLE -> "tuple(" + typeRef.fields().stream()
.map(field -> typeSurfaceKey(field.typeRef()))
.reduce((left, right) -> left + "," + right)
.orElse("") + ")";
case ERROR -> "error";
};
}
private NonFunctionKind nonFunctionKind(final PbsAst.BarrelItem item) {
if (item instanceof PbsAst.BarrelStructItem) {
return NonFunctionKind.STRUCT;

View File

@ -22,6 +22,8 @@ import java.util.List;
*/
public final class PbsParser {
private static final int MAX_NAMED_TUPLE_ARITY = 6;
private static final boolean REQUIRE_SEMICOLON = true;
private static final boolean ALLOW_TAIL_EXPRESSION = true;
public enum ParseMode {
ORDINARY,
@ -230,7 +232,7 @@ public final class PbsParser {
}
if (cursor.match(PbsTokenKind.HOST)) {
rejectAttributesBeforeUnsupportedTopDecl(pendingAttributes, "host declarations");
if (!isInterfaceMode()) {
if (isNotInterfaceMode()) {
final var end = consumeDeclarationTerminator();
report(cursor.previous(), ParseErrors.E_PARSE_RESERVED_DECLARATION,
"'declare host' is reserved and not supported in ordinary source modules");
@ -240,7 +242,7 @@ public final class PbsParser {
}
if (cursor.match(PbsTokenKind.BUILTIN)) {
consume(PbsTokenKind.TYPE, "Expected 'type' in 'declare builtin type' declaration");
if (!isInterfaceMode()) {
if (isNotInterfaceMode()) {
final var end = consumeDeclarationTerminator();
report(cursor.previous(), ParseErrors.E_PARSE_RESERVED_DECLARATION,
"'declare builtin type' is reserved and not supported in ordinary source modules");
@ -275,7 +277,7 @@ public final class PbsParser {
cursor.advance();
continue;
}
signatures.add(parseFunctionSignature(cursor.previous(), true, attributes));
signatures.add(parseFunctionSignature(cursor.previous(), attributes));
}
final var rightBrace = consume(PbsTokenKind.RIGHT_BRACE, "Expected '}' to end host declaration body");
return new PbsAst.HostDecl(
@ -305,7 +307,7 @@ public final class PbsParser {
cursor.advance();
continue;
}
signatures.add(parseFunctionSignature(cursor.previous(), true, attributes));
signatures.add(parseFunctionSignature(cursor.previous(), attributes));
}
final var rightBrace = consume(PbsTokenKind.RIGHT_BRACE, "Expected '}' to end builtin type body");
return new PbsAst.BuiltinTypeDecl(
@ -379,8 +381,8 @@ public final class PbsParser {
}
}
private boolean isInterfaceMode() {
return parseMode == ParseMode.INTERFACE_MODULE;
private boolean isNotInterfaceMode() {
return parseMode != ParseMode.INTERFACE_MODULE;
}
private boolean isOrdinaryMode() {
@ -627,7 +629,7 @@ public final class PbsParser {
cursor.advance();
continue;
}
signatures.add(parseFunctionSignature(cursor.previous(), true, attributes));
signatures.add(parseFunctionSignature(cursor.previous(), attributes));
}
final var rightBrace = consume(PbsTokenKind.RIGHT_BRACE, "Expected '}' to end contract body");
return new PbsAst.ContractDecl(name.lexeme(), ReadOnlyList.wrap(signatures), span(declareToken.start(), rightBrace.end()));
@ -730,7 +732,7 @@ public final class PbsParser {
}
private PbsAst.FunctionDecl parseFunctionLike(final PbsToken fnToken) {
final var name = consumeCallableName("Expected function name");
final var name = consumeCallableName();
consume(PbsTokenKind.LEFT_PAREN, "Expected '(' after function name");
final var parameters = parseParametersUntilRightParen();
final var rightParen = consume(PbsTokenKind.RIGHT_PAREN, "Expected ')' after parameter list");
@ -750,9 +752,8 @@ public final class PbsParser {
private PbsAst.FunctionSignature parseFunctionSignature(
final PbsToken fnToken,
final boolean requireSemicolon,
final ReadOnlyList<PbsAst.Attribute> attributes) {
final var name = consumeCallableName("Expected function name");
final var name = consumeCallableName();
consume(PbsTokenKind.LEFT_PAREN, "Expected '(' after function name");
final var parameters = parseParametersUntilRightParen();
final var rightParen = consume(PbsTokenKind.RIGHT_PAREN, "Expected ')' after parameter list");
@ -760,7 +761,7 @@ public final class PbsParser {
final var returnSpec = parseCallableReturnSpec(rightParen);
long end = returnSpec.returnType.span().getEnd();
if (requireSemicolon) {
if (REQUIRE_SEMICOLON) {
end = consume(PbsTokenKind.SEMICOLON, "Expected ';' after function signature").end();
}
@ -774,12 +775,12 @@ public final class PbsParser {
span(fnToken.start(), end));
}
private PbsToken consumeCallableName(final String message) {
private PbsToken consumeCallableName() {
if (cursor.check(PbsTokenKind.IDENTIFIER) || cursor.check(PbsTokenKind.ERROR)) {
return cursor.advance();
}
final var token = cursor.peek();
report(token, ParseErrors.E_PARSE_EXPECTED_TOKEN, message + ", found " + token.kind());
report(token, ParseErrors.E_PARSE_EXPECTED_TOKEN, "Expected a function name, but found " + token.kind());
if (!cursor.isAtEnd()) {
return cursor.advance();
}
@ -1018,14 +1019,14 @@ public final class PbsParser {
* Parses a brace-delimited block.
*/
private PbsAst.Block parseBlock() {
return parseBlock("Expected '{' to start block", true);
return parseBlock("Expected '{' to start block");
}
private PbsAst.Block parseExpressionSurfaceBlock(final String message) {
return parseBlock(message, true);
return parseBlock(message);
}
private PbsAst.Block parseBlock(final String message, final boolean allowTailExpression) {
private PbsAst.Block parseBlock(final String message) {
final var leftBrace = consume(PbsTokenKind.LEFT_BRACE, message);
final var statements = new ArrayList<PbsAst.Statement>();
PbsAst.Expression tailExpression = null;
@ -1043,7 +1044,7 @@ public final class PbsParser {
continue;
}
if (allowTailExpression && cursor.check(PbsTokenKind.RIGHT_BRACE)) {
if (ALLOW_TAIL_EXPRESSION && cursor.check(PbsTokenKind.RIGHT_BRACE)) {
tailExpression = expression;
break;
}

View File

@ -31,10 +31,6 @@ public final class PbsDeclarationSemanticsValidator {
private final NameTable nameTable;
private final PbsConstSemanticsValidator constSemanticsValidator = new PbsConstSemanticsValidator();
public PbsDeclarationSemanticsValidator() {
this(new NameTable());
}
public PbsDeclarationSemanticsValidator(final NameTable nameTable) {
this.nameTable = nameTable == null ? new NameTable() : nameTable;
}