Maison > développement back-end > Golang > le corps du texte

Test incendie : factoriel récursif

PHPz
Libérer: 2024-08-14 10:45:05
original
1146 Les gens l'ont consulté

Teste de fogo: fatorial recursivo

Pour ceux qui ne suivent pas POJ (Pascal sur la JVM) c'est un compilateur qui transforme un sous-ensemble de Pascal en JASM ( Java Assembly) afin que nous puissions utiliser la JVM comme environnement d'exécution.

Dans le dernier post, le support de read/readln de Pascal a été implémenté, des fonctions qui permettent de lire des données à partir d'une entrée standard (stdin). Dans cette publication, nous réaliserons l'un des objectifs de POJ : lire un nombre à partir d'une entrée standard et calculer la factorielle de manière récursive.

Comme nous compilons pour la JVM, il est nécessaire de détailler le fonctionnement de différents points de cette incroyable machine virtuelle. C'est pourquoi, à différents moments, je détaille le fonctionnement interne de la JVM ainsi que certaines de ses instructions (opcodes).

Factorielle récursive, la cerise sur le gâteau :-)

Comme mentionné au début du projet, un des objectifs était de pouvoir calculer la factorielle de manière récursive, en lisant le nombre à calculer à partir de l'entrée standard. Les implémentations dans POJ à ce jour ont rendu cet objectif possible :

  • Bonjour tout le monde : création de la base de code du projet avec ANTLR, analyseur et génération de code Java Assembly;
  • Opérateurs d'addition, de soustraction, de multiplication, de division et début des condamnations avec sursis - si : début de la prise en charge des opérateurs ainsi que prise en charge initiale des condamnations avec sursis ;
  • Répéter, pendant et pour : prise en charge des structures de répétition ;
  • Fonctions en Pascal : implémentation de fonctions récursives.

Le moment est désormais venu de valider ce qui a été développé jusqu’à présent. Cela dit, d'après le programme Pascal ci-dessous :

program fatorial;

var numero : integer;

function fatorial(n : integer) : integer;
begin
    if n<0 then fatorial := 0
    else begin
        if n<=1 then fatorial := 1
        else fatorial := n * fatorial(n-1);
    end;
end;

begin
    write('Introduza numero inteiro: ');
    readln(numero);
    writeln;
    writeln('O fatorial de ', numero, ' e: ', fatorial(numero));
end.
Copier après la connexion

POJ génère correctement l'assembly suivant :

// Code generated by POJ 0.1
public class fatorial {
    public static numero I

    static fatorial(I)I {
        iload 0
        sipush 0
        if_icmpge L4
        iconst 1 
        goto L5
    L4: iconst 0 
    L5: ifeq L1
        sipush 0
        istore 100
        goto L2
    L1: iload 0
        sipush 1
        if_icmpgt L9
        iconst 1 
        goto L10
    L9: iconst 0 
    L10:ifeq L6
        sipush 1
        istore 100
        goto L7
    L6: iload 0
        iload 0
        sipush 1
        isub 
        invokestatic fatorial.fatorial(I)I 
        imul 
        istore 100
L7: L2: iload 100
        ireturn 
    }

    public static main([java/lang/String)V {
        getstatic java/lang/System.out java/io/PrintStream
        ldc "Introduza numero inteiro: "
        invokevirtual java/io/PrintStream.print(java/lang/String)V

        invokestatic java/lang/System.console()java/io/Console
        invokevirtual java/io/Console.readLine()java/lang/String
        invokestatic java/lang/Integer.parseInt(java/lang/String)I
        putstatic fatorial.numero I

        getstatic java/lang/System.out java/io/PrintStream
        invokevirtual java/io/PrintStream.println()V

        getstatic java/lang/System.out java/io/PrintStream
        ldc "O fatorial de "
        invokevirtual java/io/PrintStream.print(java/lang/String)V

        getstatic java/lang/System.out java/io/PrintStream
        getstatic fatorial.numero I
        invokevirtual java/io/PrintStream.print(I)V

        getstatic java/lang/System.out java/io/PrintStream
        ldc " e: "
        invokevirtual java/io/PrintStream.print(java/lang/String)V

        getstatic java/lang/System.out java/io/PrintStream
        getstatic fatorial.numero I
        invokestatic fatorial.fatorial(I)I 
        invokevirtual java/io/PrintStream.print(I)V

        getstatic java/lang/System.out java/io/PrintStream
        invokevirtual java/io/PrintStream.println()V

        return
    }
}
Copier après la connexion

Enfin, la fin

Nous arrivons ici à la fin de ce parcours d'apprentissage avec ce projet.

Certaines choses intéressantes dans le domaine des compilateurs peuvent être explorées avec ce projet (comme l'optimisation du code généré). Qui sait, peut-être que dans un futur proche nous commencerons une nouvelle série avec des optimisations :-)

Code de projet complet

Le référentiel avec le code complet et la documentation du projet est ici.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal