對於那些不遵循POJ(JVM 上的Pascal)的人來說,它是一個將子集 從Pascal 轉換為JASM 的編譯器( Java Assembly),以便我們可以使用JVM 作為執行環境。
在上一篇文章中,我們在錯誤捕獲、對 string 類型的關係運算符的支持以及定義(和使用)Pascal 的 過程 的可能性。
在本出版品中,我們將介紹對 Pascal 函數(函數)的支持。不久之後我們就可以完成這個專案的最後一個目標:從標準輸入中讀取一個數字並計算其階乘。
當我們為 JVM 進行編譯時,有必要詳細說明這個令人難以置信的虛擬機器的各個點的功能。因此,我多次詳細介紹 JVM 的內部功能及其一些指令(操作碼)。
到目前為止,我們有一種方法來定義和呼叫 Pascal 的過程。從此 PR 中還可以定義並呼叫 Pascal 的 函數.
在此提交中,實作了一個 Java 程式來了解 JVM 如何處理定義和呼叫函數。來自下面的 Java 程式:
public class FunctionCall { public static void main(String[] args) { System.out.println("Hello from main!"); System.out.println(myMethod()); } static String myMethod() { return "Hello from myMethod!"; } }
當我們反彙編類別時,我們得到以下程式集:
1: public class FunctionCall { 2: public static main([java/lang/String)V { 3: getstatic java/lang/System.out java/io/PrintStream 4: ldc "Hello from main!" 5: invokevirtual java/io/PrintStream.println(java/lang/String)V 6: 7: getstatic java/lang/System.out java/io/PrintStream 8: invokestatic FunctionCall.myMethod()java/lang/String 9: invokevirtual java/io/PrintStream.println(java/lang/String)V 10: 11: return 12: } 13: 14: static myMethod()java/lang/String { 15: ldc "Hello from myMethod!" 16: 17: areturn 18: } 19: }
透過這個例子可以確定:
也就是說,來自下面的 Pascal 程式:
program function_call_wo_params; function myfunction : string; begin myfunction := 'Hello from myfunction!'; end; begin writeln('Hello from main!'); writeln(myfunction()); end.
POJ 已調整為產生以下 JASM:
// Code generated by POJ 0.1 public class function_call_wo_params { ;; function myfunction : string; static myfunction()java/lang/String { ldc "Hello from myfunction!" astore 100 ;; Posição 100 guarda o retorno da função aload 100 ;; Empilha o retorno da função areturn ;; Deixa "Hello from myfunction!" na pilha } ;; procedure principal (main) public static main([java/lang/String)V { ;; writeln('Hello from main!'); getstatic java/lang/System.out java/io/PrintStream ldc "Hello from main!" invokevirtual java/io/PrintStream.print(java/lang/String)V getstatic java/lang/System.out java/io/PrintStream invokevirtual java/io/PrintStream.println()V ;; writeln(myfunction()); getstatic java/lang/System.out java/io/PrintStream invokestatic function_call_wo_params.myfunction()java/lang/String invokevirtual java/io/PrintStream.print(java/lang/String)V getstatic java/lang/System.out java/io/PrintStream invokevirtual java/io/PrintStream.println()V return } }
最細心的人一定注意到了上面的「astore 100」並想到:
此提交實現了符號表和解析器中的「函數」類型的支援。
在上面的範例中,函數沒有參數。在此提交中,實現了帶有參數的函數的預期結果。來自下面的 Pascal 程式:
program function_call_with_two_params; function addvalues(value1, value2: integer) : integer; begin addvalues := value1 + value2; end; begin writeln('2+4=', addvalues(2, 4)); end.
POJ 正確產生了以下 JASM:
// Code generated by POJ 0.1 public class function_call_with_two_params { ;; function addvalues(value1, value2: integer) : integer; static addvalues(I, I)I { ;; addvalues := value1 + value2; iload 0 iload 1 iadd istore 100 iload 100 ireturn } ;; procedure main public static main([java/lang/String)V { ;; writeln('2+4=', ...); getstatic java/lang/System.out java/io/PrintStream ldc "2+4=" invokevirtual java/io/PrintStream.print(java/lang/String)V getstatic java/lang/System.out java/io/PrintStream ;; aqui código para invocar addvalues(2, 4) sipush 2 sipush 4 invokestatic function_call_with_two_params.addvalues(I, I)I ;; aqui código para invocar writeln com retorno addvalues invokevirtual java/io/PrintStream.print(I)V getstatic java/lang/System.out java/io/PrintStream invokevirtual java/io/PrintStream.println()V return } }
在下一篇文章中,我們將討論上下文、發現的錯誤、嵌套句子、資料輸入,並總結該項目的最後一個目標:遞歸計算階乘。
包含項目完整程式碼和文件的儲存庫位於此處。
以上是支援 Pascal 函數的詳細內容。更多資訊請關注PHP中文網其他相關文章!