Skip to content

feat(annotations): implémenter la validation @tailrec #44

Description

@5pilow

Contexte

L'annotation @tailrec est actuellement reconnue et stockée par le compilateur (commit 0e0bb42) mais ne valide pas encore que la fonction est effectivement récursive terminale.

Comportement attendu

// @strict
@tailrec
function sum(n, acc) {
    if (n == 0) return acc;
    return sum(n - 1, acc + n);  // ✓ tail call
}

@tailrec
function bad(n) {
    if (n == 0) return 0;
    return bad(n - 1) + 1;  // ✗ erreur: appel récursif non terminal
}

bad() doit produire une erreur de compilation ANNOTATION_TAILREC_NOT_TAIL.

Implémentation

Fichiers à modifier

  • Error.java : ajouter ANNOTATION_TAILREC_NOT_TAIL (code 159)
  • FunctionBlock.java : dans analyze(), après super.analyze(), si hasAnnotation(TAILREC) → déclencher la vérification
  • LeekReturnInstruction.java : ajouter getExpression() getter
  • src/lang/fr|en|it/leekscript.json : traduction de l'erreur 159

Algorithme

Après l'analyse du corps de la fonction, traverser récursivement les instructions :

Pour chaque instruction I dans le bloc :
  Si I est un return :
    Si son expression est directement LeekFunctionCall(this) → tail call ✓
    Si son expression contient LeekFunctionCall(this) en position non-terminale → erreur ✗
  Si I est un bloc (if/for/while) → récurser
  Pour toute autre instruction : si elle contient LeekFunctionCall(this) → erreur ✗

Un appel foo(n-1) est en position terminale si et seulement si c'est l'expression directe du return (nature FUNCTION), pas imbriquée dans une LeekExpression (opérateur binaire/unaire).

Points clés

  • LeekFunctionCall.getResolvedFunction() permet d'identifier si l'appel cible la fonction courante
  • compiler.getCurrentFunction() dans FunctionBlock.analyze() = this
  • Traversée des expressions via LeekExpression.getExpression1/2(), LeekFunctionCall params
  • Approche conservatrice : si on ne sait pas analyser une expression, la marquer comme non-tail

Références

  • Commit d'implémentation des annotations : 0e0bb42
  • Exploration faite en session — voir memory project_annotations_tailrec.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions