高阶函数
和 Scheme 一样,函数在 iScheme 中是头等对象,这意味着:
可以定义一个变量为函数。 函数可以接受一个函数作为参数。 函数返回一个函数。iScheme 的高阶函数示例
; Defines a multiply function.
(def mul (func (a b) (* a b)))
; Defines a list map function.
(def map (func (f alist)
(if (empty? alist)
(list )
(append (list (f (first alist))) (map f (rest alist)))
)))
; Doubles a list using map and mul.
>> (map (mul 2) (list 1 2 3))
>> (list 2 4 6)
小结
对 iScheme 的介绍就到这里——事实上这就是 iScheme 的所有元素,会不会太简单了? -_-
接下来进入正题——从头开始构造 iScheme 的解释程序。
解释器构造
iScheme 解释器主要分为两部分,解析(Parse)和求值(Evaluation):
1、解析(Parse):解析源程序,并生成解释器可以理解的中间(Intermediate)结构。这部分包含词法分析,语法分析,语义分析,生成语法树。
2、求值(Evaluation):执行解析阶段得到的中介结构然后得到运行结果。这部分包含作用域,类型系统设计和语法树遍历。
词法分析
词法分析负责把源程序解析成一个个词法单元(Lex),以便之后的处理。
iScheme 的词法分析极其简单——由于 iScheme 的词法元素只包含括号,空白,数字和变量名,因此C#自带的 String#Split 就足够。
iScheme的词法分析及测试
public static String[] Tokenize(String text) {
String[] tokens = text.Replace("(", " ( ").Replace(")", " ) ").Split(" trn".ToArray(), StringSplitOptions.RemoveEmptyEntries);
return tokens;
}
// Extends String.Join for a smooth API.
public static String Join(this String separator, IEnumerable<Object> values) {
return String.Join(separator, values);
}
// Displays the lexes in a readable form.
public static String PrettyPrint(String[] lexes) {
return "[" + ", ".Join(lexes.Select(s => "'" + s + "'") + "]";
}
// Some tests
>> PrettyPrint(Tokenize("a"))
>> ['a']
>> PrettyPrint(Tokenize("(def a 3)"))
>> ['(', 'def', 'a', '3', ')']
>> PrettyPrint(Tokenize("(begin (def a 3) (* a a))"))
>> ['begin', '(', 'def', 'a', '3', ')', '(', '*', 'a', 'a', ')', ')']










