programming-languages学习笔记–第6部分
1 无datatype
动态类型语言中不需要,只需要基本类型和cons.
2 Racket中的struct
(struct foo (bar baz quux) #:transparent)
3 structs的优点
定义数据类型更简洁,减少误用。
可以结合模块系统隐藏构造函数,强制不变式。
4 实现编程语言
典型的工作流:
- 具体语法(sring): "(fn x => x + x) 4"
- 解析器(生成ast): 发现错误/警告
- 类型检查: 分析ast,发现错误/警告
实现一个编程语言B的方法:
- 用另外一个语言A写一个解释器(执行器),接受一个程序B并产生结果
- 用另外一个语言A写一个编译器(转换器),转换为语言C,转换必须保证语义等价。
称A为metalanguage
不管是解释器、编译器或两者结合,都是一个具体语言的实现,不是语言定义。 所以没有一种语言比另一种语言快的说法,是语言实现的不同。
5 Interpreter
解释器可以假定什么
合法AST:
- 解释器必须处理的tree
- 可以假定解构字段的类型正确
- 不合法的AST可以导致解释器崩溃
对于解释器,metalanguage中的function可以作为解释语言的Macros.用函数接受实现语言的语法, 并返回实现语言的语法,就是宏。
6 variable and env
变量定义,环境用于映射变量到值。
7 实现闭包
env,fun
求值函数表达式:
- 函数不是一个值,closure是一个值。 求值函数返回一个closure
- 当函数求值时,创建一个包含函数和当前环境的closure
函数调用: (call e1 e2)
- 使用当前环境求值e1到一个闭包
- 使用当前环境求值e2到一个值
- 在闭包的环境中求值闭包的函数体:需要添加
- 映射函数参数名到参数值
- 对于递归,映射函数名到整个闭包
Created: 2018-12-30 Sun 12:37