目录

前文列表

用 C 语言开发一门编程语言 — 交互式解析器

用 C 语言开发一门编程语言 — 跨平台的可移植性

用 C 语言开发一门编程语言 — 语法解析器

用 C 语言开发一门编程语言 — 抽象语法树

用 C 语言开发一门编程语言 — 异常处理

用 C 语言开发一门编程语言 — S-表达式

用 C 语言开发一门编程语言 — Q-表达式

用 C 语言开发一门编程语言 — 变量元素设计

用 C 语言开发一门编程语言 — 基于 Lambda 表达式的函数设计

用 C 语言开发一门编程语言 — 条件分支

用 C 语言开发一门编程语言 — 字符串与文件加载

原生类型

目前我们的语言只封装了 C 语言中的原生 long 和 char* 类型。对于你想要做任何更加有用的计算的情况来说,这是非常有限的。更何况,我们对这些数据类型的操作也非常有限。理想情况下,我们的语言应该封装所有原生 C 数据类型,并允许操作它们的方法。其中一个最重要的补充是允许操作十进制数。为此,您应当封装 double 类型和相关运算。而且,随着数据类型的增多,我们需要确保运算符例如 + 和 - 能够很好地在它们各自或者集合上起效。

对于希望使用其语言中的十进制和浮点数进行计算的人来说,添加对原生类型的支持应该是相对来说比较有趣的。

用户定义的类型

除了添加对原生类型的支持之外,最好让用户能够添加自己的新类型,就像我们在 C 中使用结构体一样。用于执行此操作的语法或方法将取决于程序员。这是一个非常重要的部分,能使我们的语言可用于任何大小合理的项目当中去。

这个任务对于那些对如何开发语言有特定想法的人,以及对语言本身,希望其最终设计看起来像什么的人来说,这可能会很有趣。

[] 方括号的补充

有些语言使用方括号 [] 表示列表。这种语法糖用于例如 list 100 (+ 10 20) 300 的情况。通过 [],你可以写成 [100 (+ 10 20) 300]。对于希望尝试添加额外语法的人来说,这应该是一个简单的补充。

操作系统交互

这意味着封装所有 C 的功能,例如fread,fwrite,fgetc等在 Lispy 中的等同物。这是一项相当直观的任务,但确实需要编写大量的封装函数。这就是为什么到目前为止我们还没有为我们的语言做过类似的工作。

在类似的说明中,让我们的语言能够有权限并且适当地进行系统的调用是很好的。我们应该让它能够更改目录,列出目录中的文件以及诸如此类的功能。这是一项简单的任务,但同样需要封装大量的 C 函数。这对于任何想要将语言当作真实情况下的脚本语言来说,是极为重要的。

希望利用他们的语言进行简单的脚本编写任务和字符串操作的人可能对实现此项目感兴趣。

许多其他 Lisps 允许编写类似于 (def x 100) 定义值 100 到 x 上。在我们的 Lispy 中,这不会起作用,因为它会尝试计算 x 在环境中的存储为 x 的任何值。在其他 Lisps 中,这些函数称为宏,当遇到它们时,它们会停止对其参数的计算,并对它们进行未计算的操作。它们让你编写看起来像普通函数调用的东西,但实际上做的是复杂而有趣的事情。

语言中如果有这些将会很有趣。它们使语言可以为某些工作赋予一些魔力。在许多情况下,这可以使语法更好或允许用户不需要太过于单调。

我喜欢我们的语言在没有宏的时候,处理 def 和 if 的过程。但是如果你不喜欢它,也就是语言当前的工作方式,并希望它与传统的 Lisp 更相似,那么这可能是你有兴趣实现的东西。

变量哈希表

当我们查找变量名的时候,我们只是对当前环境中的所有变量进行线性搜索。我们定义的变量越多,这就变得越来越低效。

更有效的方法是实现哈希表。此技术将变量名称转换为整数,并使用此函数将索引转换为已知大小的数组,以查找与此符号关联的值。这是编程中非常重要的数据结构,并且由于其在重负载下的出色性能而无处不在。

任何有兴趣了解更多有关数据结构和算法的人都会很聪明地尝试实现这种数据结构或其中一种变体。

池分配

我们的 Lispy 很简单,但速度不快。它的性能与 Python 和 Ruby 相似。我们程序中的大多数性能开销来自这样一个问题:几乎任何过程都需要我们构造和析构 lval。因此,我们必须经常调用 malloc,这是一个很慢的函数,因为它需要操作系统为我们做一些管理。在进行计算时,会有很多 lval 类型的复制,分配和释放。

如果我们希望减少这种开销,我们需要降低 malloc 的调用次数。执行此操作的一种方法是让在程序开始时就调用一次 malloc,分配大量内存。然后我们应该调用一些函数来替换我们所有的 malloc 调用,这些函数分割并分配这个内存以便在程序中使用。这意味着我们正在模拟操作系统的一些行为,但是只是以更快的本地方式进行。这种想法称为内存池分配,是游戏开发和其他对性能特别重视的应用程序中常用的技术。

垃圾回收

几乎所有其他 Lisps 实现都为我们的变量分配不同的变量。它们不会在环境中存储值的副本,而是实际上直接指向它的指针或引用。因为使用指针而不是副本,就像在 C 中一样,使用大型数据结构时所需的开销要少得多。

如果我们存储指向值而不是副本的指针,我们需要确保在某些其他值尝试使用之前,指向的数据不会被删除。我们希望在不再引用它时删除它。执行此操作的一种方法称为 Mark 和 Sweep,用于监视环境中的值以及已分配的每个值。当一个变量被放入环境中时,它和它引用的所有内容都会被标记出来。然后,当我们希望释放内存时,我们可以迭代每个分配,并删除任何未标记的内容。

这称为垃圾回收,是许多编程语言不可或缺的一部分。与池分配一样,实现垃圾回收器不需要很复杂,但确实需要仔细完成,实现这一点对于使这种语言适用于处理大量数据至关重要。

尾调用优化

我们的编程语言使用递归来进行循环。虽然这在概念上是一种非常聪明的方法,但实际上它很差。递归函数调用自身来收集计算的所有部分结果,然后才将所有结果组合在一起。当部分结果可以累积在一个循环中时,这是一种浪费的计算方法。对于旨在运行许多或无限迭代的循环而言,这尤其成问题。

一些递归函数可以自动转换为相应的 while 循环,这些循环逐步累积总数,而不是完全累积。这种自动转换称为尾调用优化,对于使用递归进行大量循环的程序是必不可少的优化。

词法作用域

当我们的语言查找到未定义的变量时,它会抛出错误。如果能在评估程序之前告诉我们哪些变量未定义,那应当会更好。而且,这将让我们避免拼写错误和其他烦人的错误。在程序运行之前查找这些问题称为词法作用域,并使用变量定义的规则来尝试和推断哪些变量已定义,哪些完全没在程序中用上,从而不进行任何计算。

静态类型

我们程序中的每个值都要有一个相关的类型。我们在进行任何计算之前都必须确保这一点。我们的内置函数也只将某些确切的类型作为输入。我们应该能够使用此信息来推断新用户定义的函数和值的类型。在运行程序之前,我们还可以使用此信息检查是否用户使用了正确的类型调用函数。这将减少在计算之前调用具有不正确类型的函数所产生的任何错误。此检查称为静态类型。

类型系统是计算机科学中非常有趣和基本的一部分。它们是我们在运行程序之前检测错误的最佳方法。任何对编程语言安全和类型系统感兴趣的人都会发现这个项目非常有趣。

用 C 语言开发一门编程语言 — 更好的语言的更多相关文章

  1. go 语言开发中 GOPATH问题 与 go语言linux 开发环境 教程

    https://github.com/rubyhan1314/Golang-100-Days/blob/master/Day01-15(Go%E8%AF%AD%E8%A8%80%E5%9F%BA%E7 ...

  2. 安装Go语言开发环境

    安装Go语言开发环境实例代码 - 详述Go语言安装所在需要的工作:安装C语言工具,安装Mercurial,更新go到新版本等操作实例. 安装go环境 1.简介 Go是一个开源项目,采用BSD授权协议. ...

  3. 使用Sublime text 3打造一个小巧但强大的Go语言开发IDE

    版权声明:欢迎转载,转载请注明出处! https://blog.csdn.net/iTaacy/article/details/76716049 使用Sublime text 3打造一个小巧但强大的G ...

  4. 利用Scala语言开发Spark应用程序

    Spark内核是由Scala语言开发的,因此使用Scala语言开发Spark应用程序是自然而然的事情.如果你对Scala语言还不太熟悉,可 以阅读网络教程A Scala Tutorial for Ja ...

  5. 1.1 从零搭建Go语言开发环境

    一.下载 下载地址: Go官网下载地址:https://golang.org/dl/ Go官方镜像站(推荐):https://golang.google.cn/dl/ 版本的选择 Windows平台和 ...

  6. GO学习-(3) VS Code配置Go语言开发环境

    VS Code配置Go语言开发环境 VS Code配置Go语言开发环境 说在前面的话,Go语言是采用UTF8编码的,理论上使用任何文本编辑器都能做Go语言开发.大家可以根据自己的喜好自行选择.编辑器/ ...

  7. javascript——从「最被误解的语言」到「最流行的语言」

    JavaScript曾是"世界上最被误解的语言".由于它担负太多的特性.包含糟糕的交互和失败的设计,但随着Ajax的到来.JavaScript"从最受误解的编程语言演变为 ...

  8. 开发电商平台用PHP语言和JAVA语言有什么区别?哪种语言更好?

    现在很多行业都通过电子商务拓展业务,所以商城系统开发成为很多企业的刚性需求.一般有一点技术基础的客户应该知道目前商城系统开发主流语言有两个,PHP和Java.那么很多客户朋友会纠结是选择哪个语言开发好 ...

  9. Go语言开发环境配置

    一.我为什么要学习go语言 当今已经是移动和云计算时代,Go出现在了工业向云计算转型的时刻,简单.高效.内 置并发原语和现代的标准库让Go语言尤其适合云端软件开发(毕竟它就是为此而设计的).到2014 ...

  10. (转载)Go语言开发环境配置

    一.我为什么要学习go语言 当今已经是移动和云计算时代,Go出现在了工业向云计算转型的时刻,简单.高效.内 置并发原语和现代的标准库让Go语言尤其适合云端软件开发(毕竟它就是为此而设计的).到2014 ...

随机推荐

  1. JDK10的新特性:var泛型和多个接口实现

    目录 简介 实现多个接口 使用多个接口 使用var 总结 简介 在JDK10的新特性:本地变量类型var中我们讲到了为什么使用var和怎么使用var. 今天我们来深入的考虑一下var和泛型,多个接口实 ...

  2. C# Lock的用法

    当我们使用线程的时候,效率最高的方式当然是异步,即各个线程同时运行,其间不相互依赖和等待.但当不同的线程都需要访问某个资源的时候,就需要同步机制了,也就是说当对同一个资源进行读写的时候,我们要使该资源 ...

  3. 多次复制Excel符合要求的数据行:Python批量实现

      本文介绍基于Python语言,读取Excel表格文件数据,并基于其中某一列数据的值,将这一数据处于指定范围的那一行加以复制,并将所得结果保存为新的Excel表格文件的方法.   首先,我们来明确一 ...

  4. js调用摄像头,实现简单的视频展台软件

    参考文档: web api:https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices codeantenna:https://code ...

  5. HDC 2022 开发者主题演讲与技术分论坛干货分享(附课件)

     原文:https://mp.weixin.qq.com/s/axm6HyX0PqKCKksFxIfehg,点击链接查看更多技术内容.   11月4日-11月6日,HDC 2022在东莞成功举办,这是 ...

  6. 从ID3到LGB

    梳理一下树模型算法,从三种最基础的tree到lgb的全过程笔记 基于信息增益(Information Gain)的ID3算法 ID3算法的核心是在数据集上应用信息增益准则来进行特征选择,以此递归的构建 ...

  7. JWT对SpringCloud进行认证和鉴权

    JWT(JSON WEB TOKEN)是基于RFC 7519标准定义的一种可以安全传输的小巧和自包含的JSON对象.由于数据是使用数字签名的,所以是可信任的和安全的.JWT可以使用HMAC算法对sec ...

  8. 力扣38(java)-外观数列(中等)

    题目: 给定一个正整数 n ,输出外观数列的第 n 项. 「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述. 你可以将其视作是由递归公式定义的数字字符串序列: count ...

  9. 云服务器ECS共享标准型S6全新发布,行业内最具性价比

    近日,阿里云弹性计算发布全新一代云服务ECS共享标准型S6,性能相对上一代实例提升15%以上,价格相对上一代最高降低42%,是目前国内云计算厂商更能够提供的最具性价比的云服务器产品.一些中小型网站.轻 ...

  10. 阿里云张振尧:阿里云边缘云驱动5G时代行业新价值

    ​简介:近日,以"5G融合通信趋势下的技术创新"为主题的2021中国增值电信及虚拟运营高峰论坛在北京召开,阿里云边缘云高级产品专家张振尧发表了<阿里云边缘云驱动5G时代行业新 ...