Bug: É possível declarar funções sem identificador no escopo global.
Closed this issue · 6 comments
No parse.js
o método declaration()
faz o parse de um função sem nome como um expressionStatement
não entendi a verificação no primeiro if
declaration() {
try {
if (
this.check(tokenTypes.FUNÇÃO) &&
this.checkNext(tokenTypes.IDENTIFIER)
) {
this.consume(tokenTypes.FUNÇÃO, null);
return this.function("função");
}
if (this.match(tokenTypes.VAR)) return this.varDeclaration();
if (this.match(tokenTypes.CLASSE)) return this.classDeclaration();
return this.statement();
} catch (error) {
this.synchronize();
return null;
}
}
De fato, com isso o erro sai bem genérico como apenas "[Linha: 3] Erro no fim: Esperado ';' após expressão.".
Isso acontece por falta de uma verificação do identifier, o que leva o parser a não identificar um estado específico e leva para um genérico.
Possível local da correção:
Line 702 in 7b3bb09
Há também a possibilidade da criação de um functionStatement que irá verificar isso. Ou corrigir de maneira mais direta, fazendo a verificação direto no método 'declaration' e trazendo a mensagem de erro mais clara.
Fiz o seguinte, apenas removi a verificação do next token ser um INDENTIFIER
declaration() {
try {
if (this.check(tokenTypes.FUNÇÃO)) {
this.consume(tokenTypes.FUNÇÃO, null);
return this.function("função");
}
if (this.match(tokenTypes.VAR)) return this.varDeclaration();
if (this.match(tokenTypes.CLASSE)) return this.classDeclaration();
return this.statement();
} catch (error) {
this.synchronize();
return null;
}
}
``
No function já garante o próximo token ser IDENTIFIER
function(kind) {
let name = this.consume(tokenTypes.IDENTIFIER, `Esperado nome ${kind}.`);
return new Stmt.Função(name, this.functionBody(kind));
}
Show, a solução aparenta ser boa e funcional, se quiser fazer um PR, eu já avalio e testo
Beleza!