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).
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:
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.
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 } }
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 :-)
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!