ML编译器Caml Featherweight——概览
source link: http://maskray.me/blog/2014-12-24-caml-compiler-overview
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
ML编译器Caml Featherweight——概览
编译器的设计和实现大量参考了 @Zinc 和Caml Light 0.75,因此取名Caml Featherweight了……实现方面更接近于 @Zinc ,Caml Light有些晦涩复杂的地方我换成自己乱想的实现了。
tl;dr的话可以直接读源码:https://github.com/MaskRay/CamlFeatherweight
ML是个一门通用的函数式编程语言,有如下一些特点:
- 采用call-by-value的求值策略,允许副作用和imperative programming。
- 使用垃圾收集。
- 支持first-class function,函数可以像
int
、string
那样的值一样自由传递、创建。 - 实现了静态类型检查,并能自动推导类型,无需C中的类型注解。
- 提供了immutable programming的良好支持。
- 参数多态,提供了一些通用编程支持,类似于Java中的generic。
- 支持代数数据类型和模式匹配以处理复杂的数据结构。
本项目是@Zinc 提到的Zinc实验的一个实现,并大量参考了Caml Light 0.75的源码,实现了ML方言Caml的一个变体,以上提到的特性均已使用,在某些细节语法方面有省略和改动。
项目采用的Caml语言变体
基本类型:
bool
,如true
、false
char
,如’a’
、’\n’
int
,如12
、0x0e
float
,如3.0
、2e-5
string
,如hello
、world
语言内置了一些类型构造器。
’a option
,如None
、Some (4,true,7,’a’)
=
,类型为’a -> ’a -> bool
<>
,类型为’a -> ’a -> bool
==
,类型为’a -> ’a -> bool
!=
,类型为’a -> ’a -> bool
<
,类型为’a -> ’a -> bool
<=
,类型为’a -> ’a -> bool
>
,类型为’a -> ’a -> bool
>=
,类型为’a -> ’a -> bool
int
类型支持的额外操作符:+
,-
,*
,/
,mod
,分别表示加、减、乘、除、和模运算,类型均为int -> int -> int
。float
类型支持的额外操作符:+.
,-.
,*.
,/.
,即加减乘除,类型均为float -> float -> float
。
元组是几种类型的复合,可以看成几种不同类型的有序集合。元组的各个成分用逗号分割,外面套圆括号,比如:
某些地方可以省略圆括号。
可以用模式匹配抽取元组的各个成分:
元组可以把固定数目的不同元组聚合在一起,列表则可以表示相同类型的任意数目元素,语言提供的表示列表字面量的语法,如表示空列表的[]
,带有两个元素的列表[3; 4]
。
列表可以看成是一个单链表,单个节点可以为空([]
),或者包含一个元素和一个指向后继节点(对应的构造器为::
,比如:3::[]
)。::
构造器是一个操作符,是右结合的,之前提到的[3; 4]
可以看作3::4::[]
的语法糖。
数组类似于列表,可以表示相同类型的任意数目元素,并提供了随机访问的功能:
访问数组中的一个元素:
修改数组中的一个元素:
option
option
代表可能缺失的值,比如:
接受一个参数,返回参数加一的函数如下:
和类C语言不同,函数名和参数间用空格分割,并且函数体前使用=
,因为ML中没有像C那样区分语句和表达式。
如果要定义多参数的函数,参数间也用空格分割:
函数允许自递归,这时需要使用let rec
:
如果要定义互递归的函数,必须在一个let rec
中同时定义各个函数,它们之间用and
分割:
代数数据类型和模式匹配
上面定义了一个类型t
,它有三个构造器:Zero
、One
和Two
,接受不同的参数。
模式匹配和代数数据类型配套使用,可以抽取构造器的参数:
模式匹配也可用于int
、string
等基本类型。_
是通配符,可以匹配任意值:
模式匹配也可用于复杂的类型,各分支中以以小写字母开头的表示符表示变量,可以匹配任意值,从而可以在->
后的表达式中引用:
异常提供了一种中断当前的计算,报告错误,捕获错误的机制。
除数为零时会触发Division_by_zero
异常,下面的程序捕获了该异常并输出12:
如果模式匹配失败,则会产生Match_failure
异常:
try
实质上形成了一个动态作用域,如果最近的try
无法捕获的话,异常会交给外层的try
:
工具链使用说明
在项目目录下执行make
生成字节码编译器camlfwc
、字节码解释器camlfwrun
、字节码查看器camlfwod
。
编译并链接源文件得到可执行的字节码文件:
使用camlfwrun
执行:
camlfwod
可以显示目标文件或字节码可执行文件的指令列表。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK