ZVVQ代理分享网

支持 Pascal 函数(pascal函数)

作者:zvvq博客网
导读对于那些不遵循 POJ(JVM 上的 Pascal)的人来说,它是一个编译器,将子集从 Pascal 转换为 JASM(Java 程序集),以便我们可以使用 JVM 作为执行环境。 在上一篇文章中,我们在错误捕获、

对于一些不遵照 POJ(JVM 里的 Pascal)的人来讲,它是一个编译器,将子集从 Pascal 转换成 JASM(Java 程序集),便于我们可以使用JVM 做为实行环境。

在上一篇文章中,大家在错误捕捉、对 string 类别的关系运算符的支持以及界定(与使用)Pascal 过程.

的概率方面进行了一些改善在出版物中,我们将介绍对 Pascal 函数(functions)的支持。不久后大家就能完成该项目的最后一个目标:从标准输入中载入一个数字并计算其阶乘。

在我们为JVM 开展编译时,必须详细描述这一令人难以置信的虚拟机的每个点作用。因而,我多次详解JVM 的结构原理以及它的一些命令(操作码)。

适用 Pascal 函数(函数)到现在为止,我们有一种方法来定义和启用 Pascal 的过程。此后 PR 中还能够定义和启用 Pascal 的函数.

在此提交中,实现了一个Java 程序去了解JVM 怎样处理定义和调用函数。来自下边的Java程序:

公共类FunctionCall{

公共静态失效主(字符串[] args){

System.out.println("来自main的您好!");

System.out.println(myMethod());

}

静态字符串myMethod(){

回到“来自 myMethod 的您好!

}

}

在我们反汇编类时,我们得到下列程序集:

1:公共类 FunctionCall {

2:公共静态主([java/lang/String)V{

3:getstaticjava/lang/System.outjava/io/PrintStream

4:ldc“主站你好!”

5:启用虚似java/io/PrintStream.println(java/lang/String)V

6:

7:getstaticjava/lang/System.outjava/io/PrintStream

8:invokestatic FunctionCall.myMethod()java/lang/String

9:启用虚似java/io/PrintStream.println(java/lang/String)V

10:

11:回到

12:}

13:

14:静态 myMethod()java/lang/String {

15:ldc“我的方法您好!”

16:

17:回到

18:}

19:}

根据这个例子,可以知道:

为了调用方法,JVM 应用命令“invokestatic FunctionCall.myMethod()java/lang/String”(第 8 行),其中: invokestatic 是接受要调用的方式的完整签字做为参数命令; FunctionCall 是类名字; myMethod()java/lang/String 是方式的完整签字以及参数(在本例中为无)和返回类型(在本例中向 java/lang/String);命令areturn(第17行)停止函数并把回到字符串留到堆栈上。换句话说,来自下边的 Pascal 程序:

程序function_call_wo_params;

函数 myfunction :字符串;

逐渐

myfunction:=来自 myfunction 的问候!;

末尾;

逐渐

writeln(来自源程序的您好!);

writeln(myfunction());

末尾。

POJ已调节形成下列 JASM:

// POJ0.1产生的编码

公共类function_call_wo_params{

;;函数 myfunction :字符串;

静态myfunction()java/lang/String{

ldc“我函数您好!”

贮存 100 ;;第 100 位储存函数的返回值

载入 100 ;;堆栈函数返回值

收益 ;;留有“来自我功能的您好!”在堆栈中

}

;;关键程序(关键)

公共静态主([java / lang / String)V{

;;writeln(来自源程序的您好!);

getstaticjava/lang/System.outjava/io/PrintStream

ldc“主站你好!”

invokevirtualjava/io/PrintStream.print(java/lang/String)V

getstaticjava/lang/System.outjava/io/PrintStream

启用虚似java/io/PrintStream.println()V

;;writeln(myfunction());

getstaticjava/lang/System.outjava/io/PrintStream

invokestaticfunction_call_wo_params.myfunction()java/lang/String

invokevirtualjava/io/PrintStream.print(java/lang/String)V

getstaticjava/lang/System.outjava/io/PrintStream

启用虚似java/io/PrintStream.println()V

回到

}

}

最细心的人一定察觉到了上边的“astore 100”并想:

为何要把函数返回值存储在局部变量中?这是因为在 Pascal 中,函数的返回值在函数执行期间能设 N 次,但我们在JVM 中只有堆栈一次结论;为何排在第100位?函数或流程的局部变量从部位 0 逐渐,因而任意选择部位 100 来存储返回值;可是能否进行改善,确保在本例中仅形成命令ldc“Hello from myfunction!”,随后形成命令areturn?没错,没错,可是 POJ没有实现市场编译器中出现的提升环节,这可能在未来完成。此递交完成了对符号表里的“function”种类和解析器的支持。

在上面的示例中,函数没有参数。在此提交中,完成了含有参数函数的预期成果。根据下边的 Pascal 程序:

程序 function_call_with_two_params;

函数 addvalues(value1, value2: 整数) : 整数;

逐渐

加上值:=值1+值2;

末尾;

逐渐

writeln(2+4=,addvalues(2,4));

末尾。

POJ恰当生成了下列 JASM:

// POJ0.1产生的编码

公共类 function_call_with_two_params{

;;函数 addvalues(value1, value2: 整数) : 整数;

静态加值(I,I)I{

;;加上值:=值1+值2;

载入0

载入1

我加

这是100

载入100

回到

}

;;关键程序

公共静态主([java / lang / String)V{

;;writeln(2+4=,...);

getstaticjava/lang/System.outjava/io/PrintStream

LDC“2+4=”

invokevirtualjava/io/PrintStream.print(java/lang/String)V

getstaticjava/lang/System.outjava/io/PrintStream

;;这儿代码启用addvalues(2,4)

西普什2

西普什4

invokestatic function_call_with_two_params.addvalues(I,I)I

;;这儿代码启用 writeln 并返回addvalues

启用虚似java/io/PrintStream.print(I)V

getstaticjava/lang/System.outjava/io/PrintStream

启用虚似java/io/PrintStream.println()V

回到

}

}

下一步在下一篇文章中,我们将探讨前后文、发觉错误、嵌入语句、数据输入,并总结该项目的最后一个目标:递归计算阶乘。

完备的项目代码包括项目详细代码和文档的存储库在这儿。

以上就是适用 Pascal 函数的详细内容,大量请关注其他类似文章!