For those who are not following POJ (Pascal on the JVM) it is a compiler that transforms a subset from Pascal to JASM (Java Assembly) so that we can use the JVM as an execution environment.
In the last post, support for read/readln from Pascal was implemented, functions that allow reading data from standard input (stdin). In this publication we will complete one of the objectives of POJ: reading a number from standard input and calculating the factorial recursively.
As we are compiling for the JVM, it is necessary to detail the functioning of various points of this incredible virtual machine. Therefore, at various times I detail the internal functioning of the JVM as well as some of its instructions (opcodes).
As mentioned at the beginning of the project, one of the objectives was to be able to calculate the factorial recursively, reading the number to be calculated from the standard input. The implementations in POJ to date have made this objective possible:
Now the time has come to validate what has been developed so far. That said, from the Pascal program below:
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 correctly generates the following 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 } }
Here we come to the end of this learning journey with this project.
Some interesting things in the area of compilers can be explored with this project (such as optimization of generated code). Who knows, maybe in the near future we will start a new series with optimizations :-)
The repository with the project's complete code and documentation is here.
The above is the detailed content of Fire test: recursive factorial. For more information, please follow other related articles on the PHP Chinese website!