预期工作

正如你所看到的标题,我打算从零开始编写一个编程语言,之前我从未接触过编程语言相关的工作,对各项语言的编译原理也不太了解(当然大概的过程我接触过一些,不过也没有很深入的研究),我做这件事当然需要一些契机,但是最主要的还是为了做一些看起来很酷的事,至少对我来说,搞一个自己定义的编程语言,并让它能够跑起来是一件足够酷的事了。

我的目标并不大,毕竟个人用业余时间做到最后可能也只会收获一个玩具语言,相对于最终的结果,或许整个创造的过程会更有意义,更别说,我们的最终的目标是能够用它写点什么东西。

现在先来给这个还没开始的语言来上一些定义,我在做这个计划的时候,在网上搜集了很多资料,从头开始实现确实是一件很困难的事,我还为此买了一些书,不过如果遵从”原教旨”,从头到尾都自己实现,可能整个语言完成的时候,已经是很久之后了,而且确实有些技能的补充对正常的工作也不会有太大的帮助,所以整个过程我会借助一些工具,力求以比较短的时间完成整个语言的原型。

因为我的主语言是Java,答案则显而易见了,我目标要做一个jvm语言,java非常成熟,且还在不断迭代,但是它的语法确实有些臃肿,我想大家在工作中也常常遇到,比如下面是一个常见的场景

public String getProvince(User user){
   return user.getAddress().getProvince();
}

这块代码的作用是很明显是为了获取用户居住的省份,但是显而易见的这行代码又蕴含着很多问题,大家应该也很熟悉,那就是对于空值的判断,而加了判空语句会变成什么样子呢

public String getProvince(User user){
   if(user!=null){
     Address address = user.getAddress();
     if(address!=null){
       return address.getProvince();
    }
     return null;
}
}

代码突然就变得臃肿起来了,当然Java也提出了一些解决方案,比如通过注解来标识不可传空,这样IDE会在编译前帮你将问题检查出来,还有如Optional这样的类来帮助进行空值的处理,你也可以把判断条件合并用三元运算符拼在一行里,不过这些更像是弥补的措施,其它的编程语言是如何处理这些情况的呢?

比如kotlin它定义了一个新的语法?.用这个语法可以直接替代空值的判断,Java类似的问题有很多,我们有足够多的场景来扩充我们的编程语言的能力。

另外一个是Java的一些机制,比如在王垠的博客里的一道Java面试题

public static void f() {
   String[] a = new String[2];
   Object[] b = a;
   a[0] = "hi";
   b[1] = Integer.valueOf(42);
}

这段代码是能够正常编译的,但是在运行期的时候会报错,为什么会报错,则留给大家自己去研究。

选择做Jvm语言,当然也不只是因为Java臃肿不堪,需要我们来”拯救”,其实主要还是因为Java有很方便使用的库来帮助我们生成可执行的程序,我们知道Java运行是要编译为.class的字节码文件,我们作为一个jvm语言,只要做到把代码也编译成.class文件就大功告成了,而这一步可以借助很多工具,比如ASM这样的字节码操作库,Java的虚拟机规范也写的很详细。作为一个Jvm语言,我们还可以天生地链接Java原生的库,相比于从头开始写一些基本库,也减轻了不小的负担。

目标是做到什么程度:

  • 这个语言会有一个独立的文件后缀

  • 可以编写实际的应用程序

  • 在某些方面,写起来或许可以比Java本身更简洁一些

  • 可能会针对某些IDE做一些特定语法高亮的支持插件,使它更像样