用 C 语言开发一门编程语言 — 更好的语言
目录
前文列表
《用 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 语言开发一门编程语言 — 更好的语言的更多相关文章
- 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 ...
- 安装Go语言开发环境
安装Go语言开发环境实例代码 - 详述Go语言安装所在需要的工作:安装C语言工具,安装Mercurial,更新go到新版本等操作实例. 安装go环境 1.简介 Go是一个开源项目,采用BSD授权协议. ...
- 使用Sublime text 3打造一个小巧但强大的Go语言开发IDE
版权声明:欢迎转载,转载请注明出处! https://blog.csdn.net/iTaacy/article/details/76716049 使用Sublime text 3打造一个小巧但强大的G ...
- 利用Scala语言开发Spark应用程序
Spark内核是由Scala语言开发的,因此使用Scala语言开发Spark应用程序是自然而然的事情.如果你对Scala语言还不太熟悉,可 以阅读网络教程A Scala Tutorial for Ja ...
- 1.1 从零搭建Go语言开发环境
一.下载 下载地址: Go官网下载地址:https://golang.org/dl/ Go官方镜像站(推荐):https://golang.google.cn/dl/ 版本的选择 Windows平台和 ...
- GO学习-(3) VS Code配置Go语言开发环境
VS Code配置Go语言开发环境 VS Code配置Go语言开发环境 说在前面的话,Go语言是采用UTF8编码的,理论上使用任何文本编辑器都能做Go语言开发.大家可以根据自己的喜好自行选择.编辑器/ ...
- javascript——从「最被误解的语言」到「最流行的语言」
JavaScript曾是"世界上最被误解的语言".由于它担负太多的特性.包含糟糕的交互和失败的设计,但随着Ajax的到来.JavaScript"从最受误解的编程语言演变为 ...
- 开发电商平台用PHP语言和JAVA语言有什么区别?哪种语言更好?
现在很多行业都通过电子商务拓展业务,所以商城系统开发成为很多企业的刚性需求.一般有一点技术基础的客户应该知道目前商城系统开发主流语言有两个,PHP和Java.那么很多客户朋友会纠结是选择哪个语言开发好 ...
- Go语言开发环境配置
一.我为什么要学习go语言 当今已经是移动和云计算时代,Go出现在了工业向云计算转型的时刻,简单.高效.内 置并发原语和现代的标准库让Go语言尤其适合云端软件开发(毕竟它就是为此而设计的).到2014 ...
- (转载)Go语言开发环境配置
一.我为什么要学习go语言 当今已经是移动和云计算时代,Go出现在了工业向云计算转型的时刻,简单.高效.内 置并发原语和现代的标准库让Go语言尤其适合云端软件开发(毕竟它就是为此而设计的).到2014 ...
随机推荐
- 【直播回顾】OpenHarmony知识赋能五期第四课——子系统音频解读
5月12日晚上19点,知识赋能第五期第四节课<OpenHarmony标准系统多媒体子系统之音频解读>,在OpenHarmony开发者成长计划社群内成功举行. 本期课程,由深开鸿资深技术专家 ...
- Java ArrayList 与 LinkedList 的灵活选择
Java ArrayList Java ArrayList 类是一个可变大小的数组,位于 java.util 包中. 创建 ArrayList import java.util.ArrayList; ...
- Git 安全远程访问:SSH 密钥对生成、添加和连接步骤解析
使用 SSH 密钥对的 Git 安全远程访问:生成.添加和连接 SSH(Secure Shell)是一种用于安全远程访问的协议,它提供了加密通信和身份验证机制.在使用 SSH 连接到远程 Git 存储 ...
- Pandas统计计算
基本的统计方法 Method Description count Number of non-NA values describe Compute set of summary statistics ...
- Qt调用系统DLL,判断网络连接状态
*: Win32 网络连接 dll 文件名叫:wininet.dll,位置在 C:\WINDOWS\system32 目录下,将 其拷贝到项目工程下. #include <QLibrary> ...
- nginx 学习的前提
前言 在nginx 中,需要学会的是如何安装.基础的命令.看懂配置那么这时候才是一切的刚刚开始. 正文 安装可以去看菜鸟驿站的: https://www.runoob.com/linux/nginx- ...
- 分布式文件存储-FastDFS
1.1 FastDFS简介 1.1.1 FastDFS体系结构 FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了 ...
- 详细的讲一下微服务框架--SpringCloud
一:微服务架构? 1.为什么需要微服务架构 大家都知道,最开始开发系统就是单机模式(only one computer).但是随着网络的不断发展,数据不断的增加,业务不断的增加,之前在一台机器上实现的 ...
- WPF/C#:如何显示具有层级关系的数据
前言 比方说我们有以下两个类: public class Class { public string? Name { get; set; } public List<Student>? S ...
- 【vue】纯前端图形验证码实现
[vue]纯前端图形验证码实现 感觉人不能在SQL里面淹死,得看看别的东西了 因为是上班摸鱼偷摸搞的,所以人比较懒,很多东西也懒得修修改改,直接放在一个html文件下了 页面如下 js的生成图形逻辑是 ...