Z语言实现基本原理
原文作者: @TKT2016 (知乎, github)
计算机编程发展已经有几十年了,编程的难度也越来越小,会编程的人也越来越多。但是现在的编程还是非常难,需要专门学习很长时间才能掌握。我的目标是创造出更简单更容易掌握的语言,所以我开发出了Z语言。
C#语言中实现用控制台打印”你好”的程序是
Console.Write(“你好”);
对一个没有接触编程的人来说,他至少需要懂Console是什么、Write是什么、‘.’号起什么作用、“你好”为什么需要括号括起来。
在Z语言中打印“你好”的程序是这样写的
控制台打印“你好”
相比来说,Z语言程序是主要用汉字写的,和中文自然语法比较接近,需要学习的知识点更少,一般人即使没有学过,也能一眼看出这句话是什么意思。
Z语言编译为了实现正确编译上条控制台打印“你好”程序,会进行以下步骤。
一、准备实际功能类
(控制台的源文件在’Z语言系统/控制台’)
1.新建类
新建一个叫‘控制台’的C#类,给这个类名添加特性[ZStatic]。(Zstatic在‘Z语言接口编写文档’解释)
2.实现’ public static void Write(object obj)’方法
3.给‘打印(object obj)’添加‘[ZCode(“打印(object:obj)”)]’特性
二、读取Token流
编译器读取源文件,把控制台打印“你好” 分析成标识“控制台打印”和字符串“你好”两个Token
控制台打印“你好” → 控制台打印 + “你好”
三、语法分析
编译器分析导入的开发包,构建词库,根据‘[ZStatic]’标注的控制台类型和‘[ZCode(“打印(object:obj)”)]’构建两个词‘控制台’和‘打印’
四、表达式分析
编译器根据词库把‘控制台打印’分词为‘控制台’和‘打印’两个Token
控制台打印 + “你好” → 控制台 + 打印+ “你好”
五、语义分析
从控制台Token查找到控制台类型,根据打印Token查找特性为‘[ZCode(“打印(object:obj)”)]’的方法Write,把把“你好” Token作为方法调用的参数
六、生成二进制指令
编译器生成CLR调用方法指令
ldstr bytearray (60 4F 7D 59 )
call void [‘Z语言系统’]’Z语言系统’.’控制台’::Write(object)
Z语言也可以实现对参数不在末尾的方法的调用。比如下面例子。
在C#中,控制台换行实现如下
Console.WriteLine();
如果要求根据一个整数参数k连续换行k行,代码可以编写为一个方法(在’Z语言系统/控制台’)
public static void 换行(int k)
{
for (int i = 0; i < k; i++)
{
Console.WriteLine();
}
}
用C#语言调用这一方法的程序是
控制台.换行(5);
而给这个方法加特性[ZCode(“换(int:k)行”)] 后就可以在Z语言中这样调用
控制台换5行
5是参数,‘换’和‘行’是调用过程名称的组成部分。这是Z语言先进于主流编程语言的一个地方,主流编程语言中参数必须放在语句的末尾,Z语言的参数可以放在一条语句的任意位置,实现了编程的类自然语言化。
编译器对控制台换5行 这条程序的处理大概步骤如下。
一、读取Token流
控制台换5行 → 控制台换5行
二、语法分析
编译器分析导入的开发包,构建词库,根据‘[ZStatic]’标注的控制台类型和‘[ZCode(“打印(object:obj)”)]’构建两个词‘控制台’、‘换’、‘行’
三、表达式分析
对程序进行分词
控制台换5行 → 控制台 + 换 + 5 +行
四、语义分析
从控制台Token查找到控制台类型,根据换 + 5 + 行查找特性为‘ZCode(“换(int:k)行”)’的方法,把把5作为方法调用的参数
五、生成二进制指令
编译器生成CLR指令
ldc.i4.5
call void [‘Z语言系统’]’Z语言系统’.’控制台’::’换行’(int32)