O milestone 0.5.12 agora estende esse modelo ao grafo acíclico completo de procedimentos e funções.
| English | Português (Brasil) |
O milestone 0.5.11 substitui o modelo incondicional de 16 bytes baseado na profundidade da AST por alocação determinística em tempo de compilação baseada no número máximo real de valores simultaneamente ativos. A mudança afeta o armazenamento do compilador, não a sintaxe nem a semântica aritmética do NES Pascal. Functions continuam não implementadas.
TemporaryPool aluga o slot numerado livre de menor índice, registra as
quantidades atual e máxima de slots ativos e exige liberação explícita. O backend
e a análise anterior ao layout usam as mesmas regras de adquirir/usar/liberar:
A.Expressões sequenciais reutilizam expression_temporary_0 em vez de acumular
armazenamento. Uma expressão aninhada à esquerda pode manter os slots 0, 1, 2 e
seguintes ativos sem conflito. O emissor é limitado pela quantidade reservada
pela análise de memória e assegura internamente que o pico emitido coincide
exatamente com a reserva.
Imediatos diretos, operandos de memória direta seguros, redução booleana
orientada a branches e eliminação local de testes contra zero da 0.5.7 não
mudaram. A aritmética de byte continua usando ADC/SBC do 6502 e fazendo
wraparound módulo 256.
Escopos de chamada preservam todo aluguel pertencente ao chamador. Redução aninhada recebe o mesmo pool e só pode adquirir um slot não alugado. Chamadas de valor de builtins atuais já atravessam esse limite. A futura análise de Functions deverá estender a mesma regra pelo grafo de chamadas e atribuir slots sem sobreposição a cada cadeia ativa chamador/chamado. Este é um modelo pertencente ao chamador em tempo de compilação; o milestone não adiciona frames de runtime, valores de retorno ou Functions.
Argumentos de procedimentos mantêm a preparação da esquerda para a direita: cada argumento é totalmente avaliado e armazenado no parâmetro antes do próximo. Argumentos de builtins mantêm a ordem definida pelo emissor. As expressões atuais da linguagem não expõem um efeito colateral de usuário forte o bastante para um oráculo de ordem em runtime, portanto testes focados de Assembly também fixam a sequência existente, direita-primeiro, para expressões complexas.
Escritas em arrays e arrays de records com índice variável continuam salvando o
índice calculado na pilha de hardware do 6502 durante a avaliação do lado direito.
Esse uso da pilha é separado dos slots de expressão na Zero Page. Leituras como
Values[Indexes[I]], índices escalados de records, escritas indexadas, argumentos
de procedimentos e de builtins usam o mesmo pool de expressão com escopo.
O armazenamento do compilador é reportado em categorias separadas:
for_limit_*, contados separadamente;A capacidade combinada de expressão/cache permanece em 16 bytes em
$0010-$001F. Símbolos reais ocupam o prefixo; o sufixo não usado aparece como
Recovered temporary Zero Page e fica livre para o alocador. A janela explícita
futura continua em $0020-$007F e a promoção automática em $0080-$00FF, sem
mover endereços existentes de usuário na Zero Page.
Se slots de expressão mais caches ultrapassarem 16 bytes, a compilação falha com
E5004. O diagnóstico informa o requisito combinado, seus componentes de
expressão e cache e a capacidade disponível. Ele nunca reutiliza um slot ativo,
toma espaço da promoção opcional ou faz spill silencioso.
| Caso | Pico de slots de expressão | Resultado |
|---|---|---|
| aritmética direta / programas simples | 0 | sem expression_temporary_0; 16 bytes de ZP recuperados |
Values[I] + Values[J] |
1 | somente slot 0 |
(Values[I] + Values[J]) + Values[K] |
2 | slots 0 e 1 sem conflito |
((Values[I] + Values[J]) + Values[K]) + Values[L] |
3 | slots 0, 1 e 2; statements posteriores os reutilizam |
| comparação aninhada | 2 | resultado aritmético e operando da comparação permanecem distintos |
| soma indexada aninhada à esquerda com 18 termos | 17 | E5004 determinístico contra a capacidade de 16 bytes |
A regressão de runtime verifica aritmética com três slots, wraparound
$F0 + $20 = $10, reutilização sequencial, índices aninhados de arrays,
escritas indexadas, leitura e escrita de arrays de records, materialização de
comparação aninhada e duas expressões em argumentos de procedimento. O golden
focado registra cada declaração e uso de temporário.
Janela fixa legada é a antiga janela combinada de 16 bytes para
temporários/caches. Nova expressão contém apenas a reserva de expressão; os
caches aparecem separados. ZP líquida salva desconta caches ainda necessários.
| Benchmark | Janela fixa legada | Pico real | Nova expressão | Outros caches | ZP líquida salva | ZP aloc./reservada antiga | ZP aloc./reservada nova | ZP livre antiga | ZP livre nova |
|---|---|---|---|---|---|---|---|---|---|
minimal |
16 B | 0 | 0 B | 0 B | 16 B | 25 B | 9 B | 128 B | 144 B |
arithmetic |
16 B | 0 | 0 B | 0 B | 16 B | 25 B | 9 B | 128 B | 144 B |
boolean_expressions |
16 B | 0 | 0 B | 0 B | 16 B | 26 B | 10 B | 127 B | 143 B |
conditionals |
16 B | 0 | 0 B | 0 B | 16 B | 27 B | 11 B | 126 B | 142 B |
loops |
16 B | 0 | 0 B | 0 B | 16 B | 28 B | 12 B | 125 B | 141 B |
counting |
16 B | 0 | 0 B | 6 B | 10 B | 28 B | 18 B | 125 B | 135 B |
procedures |
16 B | 0 | 0 B | 0 B | 16 B | 28 B | 12 B | 125 B | 141 B |
procedure_parameters |
16 B | 0 | 0 B | 0 B | 16 B | 27 B | 11 B | 126 B | 142 B |
controller_input |
16 B | 0 | 0 B | 0 B | 16 B | 30 B | 14 B | 123 B | 139 B |
sprite_support |
16 B | 0 | 0 B | 0 B | 16 B | 26 B | 10 B | 127 B | 143 B |
metasprite_player |
16 B | 0 | 0 B | 0 B | 16 B | 34 B | 18 B | 123 B | 139 B |
sprite_animation |
16 B | 0 | 0 B | 0 B | 16 B | 34 B | 18 B | 123 B | 139 B |
palette_support |
16 B | 0 | 0 B | 0 B | 16 B | 25 B | 9 B | 128 B | 144 B |
background_updates |
16 B | 0 | 0 B | 0 B | 16 B | 25 B | 9 B | 128 B | 144 B |
frame_callbacks |
16 B | 0 | 0 B | 0 B | 16 B | 25 B | 9 B | 128 B | 144 B |
scrolling_ppu_state |
16 B | 0 | 0 B | 0 B | 16 B | 25 B | 9 B | 128 B | 144 B |
arrays |
16 B | 1 | 1 B | 2 B | 13 B | 28 B | 15 B | 125 B | 138 B |
enumerations |
16 B | 0 | 0 B | 0 B | 16 B | 26 B | 10 B | 127 B | 143 B |
records |
16 B | 0 | 0 B | 0 B | 16 B | 27 B | 11 B | 126 B | 142 B |
gameplay_full_stack |
16 B | 0 | 0 B | 0 B | 16 B | 33 B | 17 B | 124 B | 140 B |
No corpus de 20 programas, a soma comparativa das economias por programa é
311 bytes. Dezenove benchmarks agora reservam zero bytes de expressão; arrays
reserva um. counting mantém seis bytes de cache de laço e arrays mantém dois,
sem rotulá-los como temporários de expressão. O pico entre benchmarks é um; a
regressão focada prova um padrão natural de três slots e o fixture de exaustão
prova o tratamento de requisitos mais profundos.
A mudança altera somente reserva de dados e relatórios de mapa. Todos os benchmarks mantiveram tamanho de PRG, instruções e ciclos estáticos estimados.
| Benchmark | PRG código/ocupada | Instruções | Ciclos estáticos estimados |
|---|---|---|---|
minimal |
239/245 B | 108 | 367 |
counting |
488/494 B | 216 | 700 |
arrays |
382/388 B | 182 | 569 |
records |
389/395 B | 196 | 605 |
gameplay_full_stack |
3.350/3.356 B | 815 | 2.712 |
Em gameplay_full_stack, a contabilidade atual tem 17 bytes de ZP
alocados/reservados por compilador/runtime/usuário, 1.004 bytes de RAM comum de
runtime/usuário, shadow de OAM de 256 bytes, 256 bytes reservados pela pilha de
hardware, 99 bytes de ZP indisponíveis por política e 416 bytes livres visíveis
ao alocador (140 ZP + 276 comuns). Portanto, 1.277 bytes são alocados/reservados
por compilador/runtime/usuário e 1.632 bytes do espaço da CPU estão
comprometidos/reservados. As categorias mais memória livre reconciliam
exatamente os 2.048 bytes do NES.
A validação local passou em 475 testes automatizados não-Mesen e nos 28 testes
headless dedicados do Mesen. O corpus completo de 20 benchmarks montou e linkou,
todos os exemplos públicos foram compilados pela suíte de integração da cadeia
de ferramentas, a compilação de bytecode Python passou e git diff --check não
reportou erros.
Functions, valores de retorno, frames de pilha, spilling, alocador geral de registradores, CFG/SSA/dataflow e reordenação de expressões continuam adiados.