1966年公开的语言设计

1966年6月(公历),尼克劳斯·维尔特(Niklaus Wirth)与C. A. R. 霍尔(C. A. R. Hoare)在《Communications of the ACM》发表《关于ALGOL发展的贡献》。这份设计成为后来ALGOL W实现的基础;论文发表、编译器实现和教学文档编成,是彼此衔接的几个阶段。

方案起于国际信息处理联合会(IFIP)第2.1工作组对ALGOL 60后继语言的讨论。维尔特在1965年5月普林斯顿会议上受邀起草文件;同年10月的讨论认为其推进幅度不足,草案不再保有工作组正式文件地位。两位作者继续修改,加入霍尔提出的记录结构等内容,并说明公开论文是为了交流设计、鼓励实验实现,而非恢复其正式候选资格。

参考:[1] [2]

在可实现与可表达之间取舍

作者希望语言既能有效利用计算机,又能清楚交流算法,并服务教学与研究。应用范围也要从代数和数值计算延伸到模拟、信息检索、图论等领域。为此,设计加入复数、较高精度的数值类型、位串和字符串,同时简化若干控制结构。

记录与引用尤其适合描述非数值关系。数组的元素通常同属一种类型,记录却可以把年龄、姓名等不同类型的字段放在一起,再用引用连接另一条记录。原论文举出age(B)取得某人的年龄、age(father(B))取得其父亲年龄的例子,把关系的表达放进程序语言,而不只交给程序员自行安排数值地址。

参考:[1]

把方案做成IBM System/360编译器

在斯坦福大学,维尔特发起并指导实现项目,亨利·鲍尔(Henry R. Bauer)、谢尔登·贝克尔(Sheldon Becker)和苏珊·格雷厄姆(Susan L. Graham)承担编译器的大部分编程。Joseph W. Wells, Jr.和Edwin H. Satterthwaite, Jr.负责编译器所在的PL360系统、连接部分及装入程序;斯坦福直线加速器中心和校内计算中心提供机时。

1968年1月的CS86报告已把ALGOL W说明为在IBM 360上实现的语言,同年5月20日的CS98报告进一步详述内部结构。实现者并未机械照搬1966年论文:字符串的定义和操作、复数表示有所调整;并行处理和数据文件功能虽被考虑过,却因会迫使已写好的编译器部分大幅修改而放弃。

参考:[2] [3]

一个记录创建程序

1968年1月的入门讲义用一个短程序说明记录的创建与初始化,按原例整理空格如下:

BEGIN RECORD H(INTEGER C,D; STRING(2) S); REFERENCE(H) R1; R1 := H(5,8,"AZ") END.

RECORD声明H类记录有两个整数字段C、D,以及两个字符位置的字符串字段S;REFERENCE声明R1只能引用H类记录。真正执行H(5,8,"AZ")时,程序才创建记录,依声明次序把5、8和“AZ”放入各字段,并把引用交给R1。随后用C(R1)便可指定其中的C字段。

这里声明记录类别不等于已经创建一条记录,引用变量也不等于整个记录内容。讲义先展示分别创建、逐字段赋值的写法,再给出这个合并写法,让学习者看到两种形式如何完成相同初始化。讲义把类别定义、实例创建和字段访问分开说明,既教授写法,也解释运行时会发生什么。

参考:[2]

三遍处理与错误检查

CS98把编译器分为三遍。第一遍扫描源程序,转换符号和数值常量、去除注释与空白,并建立体现程序块层次的名字表;第二遍分析语法、检查错误和分配静态存储,形成供生成代码使用的二叉树;第三遍才生成机器代码。这三部分分别用PL360编写。

实现团队把可靠性和效率同时列为目标:能在编译时算出的常量运算先行计算,但不进行把计算移出循环等重排优化。只有前面的检查没有发现错误,第三遍才运行;运行时仍检查数组下标范围、子串操作和形式过程参数。错误信息还指出问题在源程序中的位置,方便使用者回到程序修改。

参考:[3]

从设计论文到入门材料

CS86不只有语法定义,还收录入门课程讲义、卡片作业安排、设备说明和错误信息。讲义先对照既有ALGOL 60教材说明差异,再介绍新增功能。例如READON从当前数据卡继续寻找数值,而READ从新卡开始读;这些说明把抽象语言规则接到学生实际提交作业的方式上。

由此可见,ALGOL W的早期成果既有1966年的公开设计,也有随后在斯坦福形成的实现和教学材料。记录、引用与类型检查获得了具体语法和执行机制,设计中的扩展也经受了机器与编译工作量的限制。其早期历史正呈现为这些取舍被写成程序、说明书和课程例子的过程。

参考:[1] [2] [3]