Brandtest: rekursive Fakultät

PHPz
Freigeben: 2024-08-14 10:45:05
Original
1149 Leute haben es durchsucht

Teste de fogo: fatorial recursivo

Für diejenigen, die POJ (Pascal auf der JVM) nicht befolgen: Es handelt sich um einen Compiler, der eine Teilmenge von Pascal in JASM umwandelt ( Java Assembly), damit wir die JVM als Ausführungsumgebung verwenden können.

Im letzten Beitrag wurde die Unterstützung für read/readln von Pascal implementiert, Funktionen, die das Lesen von Daten aus der Standardeingabe (stdin) ermöglichen. In dieser Veröffentlichung werden wir eines der Ziele von POJ erfüllen: eine Zahl aus der Standardeingabe lesen und die Fakultät rekursiv berechnen.

Während wir für die JVM kompilieren, ist es notwendig, die Funktionsweise verschiedener Punkte dieser unglaublichen virtuellen Maschine im Detail zu beschreiben. Daher erläutere ich an verschiedenen Stellen die interne Funktionsweise der JVM sowie einige ihrer Anweisungen (Opcodes).

Rekursive Fakultät, das i-Tüpfelchen :-)

Wie zu Beginn des Projekts erwähnt, bestand eines der Ziele darin, die Fakultät rekursiv berechnen zu können, indem man die zu berechnende Zahl aus der Standardeingabe liest. Die bisherigen Implementierungen in POJ haben dieses Ziel möglich gemacht:

  • Hallo Welt: Habe die Codebasis des Projekts mit ANTLR, Parser und Codegenerierung Java Assembly;
  • erstellt
  • Additions-, Subtraktions-, Multiplikations-, Divisionsoperatoren und der Beginn von Bedingungssätzen – wenn: Unterstützung für Operatoren sowie anfängliche Unterstützung für Bedingungssätze begonnen hat;
  • Wiederholen, während und für: Unterstützung für Wiederholungsstrukturen;
  • Funktionen in Pascal: Implementierung rekursiver Funktionen.

Jetzt ist es an der Zeit, die bisherigen Entwicklungen zu validieren. Das heißt, aus dem Pascal-Programm unten:

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.
Nach dem Login kopieren

POJ generiert korrekt die folgende Assembly:

// 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
    }
}
Nach dem Login kopieren

Endlich das Ende

Hier kommen wir mit diesem Projekt zum Ende dieser Lernreise.

Einige interessante Dinge im Bereich Compiler können mit diesem Projekt erkundet werden (z. B. Optimierung des generierten Codes). Wer weiß, vielleicht starten wir in naher Zukunft eine neue Serie mit Optimierungen :-)

Vollständiger Projektcode

Das Repository mit dem vollständigen Code und der Dokumentation des Projekts finden Sie hier.

Das obige ist der detaillierte Inhalt vonBrandtest: rekursive Fakultät. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage