我在 JavaScript 中有自己的 Lisp 解释器,我已经工作了一段时间,现在我想实现像 Common Lisp 中的阅读器宏。
我已经创建了 Streams(除了特殊符号之外几乎可以工作,@ , ` '
),但是当它加载包含脚本的页面(具有 400 行代码的lisp 文件)时,它会冻结浏览器几秒钟。这是因为我的 Streams 是基于 substring 函数的。如果我首先拆分令牌,然后使用迭代令牌的 TokenStream,它工作正常。
所以我的问题是,字符串流真的是 Common Lisp 中的东西吗?您能否在 CL 中添加创建全新语法(如 Python)的阅读器宏,这简化了我是否可以实现"""
宏(不确定是否可以将 3 个字符作为阅读器宏)或其他将在 lisp 中实现模板文字的字符,例如:
(let ((foo 10) (bar 20))
{lorem ipsum ${baz} and ${foo}})
或者
(let ((foo 10) (bar 20))
""lorem ipsum ${baz} and ${foo}"")
或者
(let ((foo 10) (bar 20))
:"lorem ipsum ${baz} and ${foo}")
会产生字符串
"lorem ipsum 10 and 20"
在 Common Lisp 中是否可能发生这样的事情,实现#\{
或#\:
作为阅读器宏有多难?
我能想到的在 Lisp 中使用模板文字的唯一方法是这样的:
(let ((foo 10) (bar 20))
(tag "lorem ipsum ${baz} and ${foo}")))
其中 tag 是返回带有 ${} 作为自由变量的字符串的宏。阅读器宏也可以返回被评估的 lisp 代码吗?
还有一个问题,你可以像这样实现阅读器宏:
(list :foo:bar)
(list foo:bar)
其中 : 是阅读器宏,如果它在符号之前,它将符号转换为
foo.bar
如果它在里面,它会抛出错误。我问这个是因为使用基于令牌的宏:foo:bar
并且foo:bar
将是符号并且不会被我的阅读器宏处理。
还有一个问题可以将阅读器宏放在一行中,第二行使用它吗?这肯定只有字符串流才有可能,而我测试过的解释器用 JavaScript 编写的解释器是不可能的。