Matrix42 / playscript-java

极客时间-《编译原理之美》playScript 脚本语言相关代码,其已包含编译后的源码,可自行测试,同时也包含了 Idea 相关的配置,可自行修改并重新编译

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

playscript(java版本)

playscript是在准备《编译原理之美》课程期间开发的一门脚本语言。主要用来展示编译器的前端技术。
这门语言目前实现的特征是:

  • 语法特征总体上比较像java,因为这一版本的词法和语法规则文件都是借鉴java语言的规则。
  • 静态类型:支持int、long、float、double等基础数据类型。
  • 支持函数,并且函数是一等公民,可以嵌套声明函数,支持闭包。
  • 支持面向对象特性。

构建和开发

从代码库中克隆下代码以后,可以基于源代码构建一个项目。 或者使用里面原来带的idea项目文件。 后面我将提供Maven的项目文件。
本项目依赖Antlr的运行库。相应的jar包已经包含在了lib目录下。
在idea项目中,我设置了一个PlayScript scratch任务,可以解析执行examples目录中的scratch.play文件。你可以在这个文件里随意写一些脚本,并编译执行,或者跟踪调试。

编译前准备和编译后配置

编译前

需要在项目结构里面设置依赖库,否则编译失败

QQ截图20200116151308.png

编译后

需要在环境变量中设置 依赖库的 CLASSPATH

windows 系统 为例:

D:\IdeaProjects\playscript-java\out\production\playscript-java\;D:\IdeaProjects\playscript-java\lib\*

运行playscript

在运行之前:

  • 要设置好本机的java环境;
  • 设置好CLASSPATH,让java能够找到play包中的类。

命令行工具 java play.PlayScript

usage: 
  java play.PlayScript [-h | --help | -o 输出文件 | -S | -v | -ast-dump] [脚本文件]  
	-h or --help : 打印帮助信息 
	-v verbose mode : 转储AST和符号   
	-ast-dump : 以Lisp样式转储AST   
	-o outputfile : 用于保存生成的代码的文件路径名,例如:汇编代码   
	-S : 编译为汇编代码   
	scriptfile : 文件包含的脚本代码  

举例:

java play.PlayScript
这将启动一个REPL界面,在里面输入脚本,并解释执行。

java play.PlayScript -v
REPL模式,并打印AST和符号表

java play.PlayScript scratch.play
编译和执行scratch.play脚本

java play.PlayScript -v scratch.play
编译和执行scratch.play脚本,并输出AST和符号表

简化命令的方式

mac os X / linux / unix

设置阁下的bash命令,可以使用起来更方便。 比如,我在.bash_profile文件中添加了:

alias play='java play.PlayScript'

这样,运行一个.play脚本的时候,可以很简单:

play scratch.play

windows 系统用户

设置阁下的 cmder 快捷命令,使用起来也比较方便

阁下可以下先查看我之前写的配置 cmder 的快捷命令的文章,如下所示

windows cmder 仿 mac 操作习惯配置 命令行 - 疯狂的AI

之后阁下可以在最后一行添加如下代码:

play=java play.PlayScript $*

这样,运行一个.play脚本的时候,可以很简单:

play scratch.play

examples目录中的示例脚本

添加了一些示例脚本,来演示playscript的功能,大家可以玩一玩!

  • expressions.play 各种表达式功能。
  • BlockScope.play 块作用域。
  • loop.play for和while循环,以及break语句。
  • function.play 基本的函数功能。
  • regression.play 递归函数功能。递归函数对语义分析有一定要求,要在函数定义完毕之前就能引用它。这个例子用递归方式显现了斐波那契数列的计算。
  • FirstClassFunction.play 作为一等公民的函数,可以像数值一样给变量赋值,或者作为函数参数和返回值。
  • LinkedList.play 实现了一个简单的链表,并且演示了高阶函数功能,有点像javascript的map函数。
  • closure.play 基础的闭包特性。
  • closure-fibonacci.play 用闭包特性实现了斐波那契数列的计算。
  • closure-mammal.play 用闭包特性实现了斐波那契数列。这个闭包特性还比普通的函数闭包更强。它能让多个函数共享一个闭包,就像对象的多个方法可以共享对象属性一样。
  • UseBeforeDeclare.play 对于各种自定义类型和类的成员,可以在声明之前就使用。语义分析时能正确的解析出来。
  • ClassTest.play 面向对象的基本特性,包括构造函数、缺省构造函数、访问对象属性和方法。
  • mammal.play 演示面向对象功能,比如继承和多态。

项目中主要的示例代码


About

极客时间-《编译原理之美》playScript 脚本语言相关代码,其已包含编译后的源码,可自行测试,同时也包含了 Idea 相关的配置,可自行修改并重新编译


Languages

Language:Java 93.5%Language:ANTLR 6.5%