标签: reader-macro

定义我自己的读取宏

Common Lisp中有一些读取宏' #' #P,但是如何编写读取宏呢?

像这样:

#T"hello world"
====================>
(gettext "hello world")
Run Code Online (Sandbox Code Playgroud)

lisp common-lisp reader-macro

5
推荐指数
1
解决办法
153
查看次数

cl-mysql代码中"#+"的含义是什么?

最近我试着阅读关于cl-mysql的代码,但是却陷入了困境#+.

试图google它,但没有工作,所以转到这里

(defun make-lock (name)
  #+sb-thread (sb-thread:make-mutex :name name)
  #+ecl (mp:make-lock :name name)
  #+armedbear (ext:make-thread-lock)
  #+ (and clisp mt) (mt:make-mutex :name name)
  #+allegro (mp:make-process-lock :name name))
Run Code Online (Sandbox Code Playgroud)

看起来它适用于不同的后端lisp编译器.但仍然不知道为什么写这样的东西.他说,任何人都可以帮助我说清楚.

common-lisp reader-macro

5
推荐指数
2
解决办法
148
查看次数

如何在阅读器宏中评估Lisp代码?

我在Common Lisp中编写自己的x86-64汇编程序,它为x86-64的子集生成正确的二进制代码.我使用自定义阅读器宏将汇编代码转换为语法树,并按预期工作.

我试图完成的是允许在汇编代码中使用Lisp代码,这样我可以使用Lisp作为汇编程序的宏语言.我#a用作宏调度字符并#e为读者发出信号.内部读者#l更改为Lisp模式并#a返回到汇编模式#e(对于读取器宏的信号结束)应该在两种模式下都有效.

我不明白的是如何将评估代码的结果输出回输入流(在其余代码之前处理),或者如何再次读取Lisp代码输出,以便输出可以适当地处理Lisp代码(它将是汇编代码)(与汇编代码的其余部分相同).我怎样才能实现这一目标?

旁注:这是我的第一个读者宏,因此可能存在设计缺陷.我认为我将Lisp代码读入字符串的方法不一定是最好的方法,如果有一些更短和更惯用的方法来做到这一点.

这是我的阅读器宏的简化版本:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defun get-last-character-string (my-string)
    "This function returns a string consisting of the last character of the input string."
    (subseq my-string (1- (length my-string))))

  (defun get-string-without-last-character (my-string) 
    "This function returns a string without the last character of the input string."
    (subseq my-string 0 (1- (length my-string))))

  (defun get-string-without-invalid-last-character (my-string invalid-last-characters)
    "If the last character of …

lisp common-lisp reader-macro

4
推荐指数
1
解决办法
788
查看次数

Common Lisp Hash-Dot#.读者宏

最近,我遇到了所谓的哈希点Common Lisp阅读器宏,我想知道它是如何工作的以及它的作用.使用搜索引擎没有多大帮助,所以任何示例,解释和特别是用例都是最受欢迎的.

common-lisp reader-macro

4
推荐指数
1
解决办法
220
查看次数

Common Lisp中的反引用:read和eval

这个问题在一定程度上重新接种到这个这个对elisp的.基本上,如何读取和评估反向报价?正在发生什么过程?标准是否对此有所说明?

这是我所期望的,但它不会发生:符号`是一个读者宏 - 并被翻译成某种(BACKQUOTE ...)宏/特殊形式(类似于'被翻译(QUOTE ...)).这不会发生,事实上,Common Lisp甚至没有BACKQUOTE宏.

发生了什么(SBCL):

CL-USER> (defparameter *q* (read-from-string "`(a b ,c)"))
*Q*
CL-USER> *q*
`(A B ,C)
CL-USER> (car *q*)
SB-INT:QUASIQUOTE
CL-USER> (cdr *q*)
((A B ,C))
Run Code Online (Sandbox Code Playgroud)

与预期有所不同,但还可以.现在,,C它本身就是一个有趣的野兽:

CL-USER> (type-of (third (cadr *q*)))
SB-IMPL::COMMA
Run Code Online (Sandbox Code Playgroud)

如果没有逗号符号,则评估读取表达式是正常的:

CL-USER> (eval (read-from-string "`(a b c)"))
(A B C)
Run Code Online (Sandbox Code Playgroud)

但是如果我想用本地绑定来评估原始表达式C,则存在一个问题:

(let ((c 10)) (eval (read-from-string "`(a b ,c)")))
; in: LET ((C 10)) …
Run Code Online (Sandbox Code Playgroud)

lisp elisp common-lisp reader-macro

3
推荐指数
1
解决办法
275
查看次数

在Common Lisp中管理读者宏

我想以这样的方式定义读取器宏,它们只影响某个包/文件.

到目前为止,我能够加载这些文件

(let ((*readtable* (copy-readtable)))
  (load "file.lisp"))
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法呢?

lisp common-lisp reader-macro

2
推荐指数
1
解决办法
410
查看次数

使用#aka read-macro

由Doug Hoyte阅读的书"Let Over Lambda",我发现了以下对#.符号的描述,即read-macro:

使用COMMON LISP内置的基本读取宏是#.读取时间eval宏.此读取宏允许您将对象嵌入到您读取的无法序列化的表单中,但可以使用一些lisp代码创建.

它来自第4章,本书的大部分内容可以在这里找到:http: //letoverlambda.com/index.cl/toc

这是本书中的示例,显示了每次都可以以不同的方式读取相同的表达式:

* '(football-game
     (game-started-at
       #.(get-internal-real-time))
     (coin-flip
       #.(if (zerop (random 2)) 'heads 'tails)))

(FOOTBALL-GAME
  (GAME-STARTED-AT 187)
  (COIN-FLIP HEADS))

* '(football-game
     (game-started-at
       #.(get-internal-real-time))
     (coin-flip
   #.(if (zerop (random 2)) 'heads 'tails)))

(FOOTBALL-GAME
  (GAME-STARTED-AT 309)
  (COIN-FLIP TAILS))
Run Code Online (Sandbox Code Playgroud)

接下来,作者演示了一些硬核技巧,用#宏创建变体.

因此,事实证明它#'也是某种读取宏,它通常在表示函数名称的符号之前使用.但这是否必要,他的工作到底是什么?

我可以在有#'或没有它的情况下为高阶函数添加符号:

CL-USER> (defun test nil t)
TEST
CL-USER> (funcall #'test)
T
CL-USER> (funcall 'test)
T
Run Code Online (Sandbox Code Playgroud)

取得同样的成功.

lisp common-lisp reader-macro

2
推荐指数
2
解决办法
294
查看次数

在常见的lisp中更改默认阅读器

我写了一些可以取代read普通lisp 功能的函数

(defun my-read (stream &rest args)
  (declare (ignore args))
  (funcall (my-get-macro-character (read-char stream))))
Run Code Online (Sandbox Code Playgroud)

有没有办法将此功能用作默认阅读器?

common-lisp stream reader-macro reader

2
推荐指数
1
解决办法
237
查看次数

Common Lisp No Dispatch Character Defined

我目前正在阅读Paul Graham的"On Lisp"一书中关于读时宏的章节.

我遇到的问题如下.当我运行他的一个例子时:

(set-dispatch-macro-character #\# #\?
  #’(lambda (stream char1 char2)
    ‘#’(lambda (&rest ,(gensym))
       ,(read stream t nil t))))
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

No dispatch function defined for #\’
Run Code Online (Sandbox Code Playgroud)

为什么会这样?可能是因为我在REPL上运行它吗?有什么可以解决它?

syntax common-lisp reader-macro

2
推荐指数
1
解决办法
107
查看次数

Common Lisp 中读取器宏的限制是什么

我在 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}})
Run Code Online (Sandbox Code Playgroud)

或者

(let ((foo 10) (bar 20))
  ""lorem ipsum ${baz} and ${foo}"")
Run Code Online (Sandbox Code Playgroud)

或者

(let ((foo 10) (bar 20))
  :"lorem ipsum ${baz} and ${foo}")
Run Code Online (Sandbox Code Playgroud)

会产生字符串

"lorem ipsum 10 and 20"
Run Code Online (Sandbox Code Playgroud)

在 Common Lisp 中,这样的事情是可能的,实现 …

lisp macros common-lisp reader-macro

2
推荐指数
1
解决办法
408
查看次数

用于“惰性中缀或”的通用 Lisp 读取宏,以解构关键字

我有一个 Common Lisp 阅读器宏来解析“或”关系的惰性/延迟声明,使用由管道符(“|”)分隔的中缀语法以及标准列表括号和关键字文字。考虑形式 (:a :b|:c) - 它表示一个 2 部分元组,其中第一个元素肯定是 :a,第二个元素是 :b 或 :c。例如,可以推断整个元组的有效形式是 (:a :b) 或 (:a :c)。

我已经有函数封装的逻辑来解构 read 宏之后的这些元组列表形式。但在阅读时,我需要解析像 :a|:b|:c 这样的形式,并用移除的管道标记它,比如 (:lazy-or :a :b :c)。中缀语法的使用纯粹是为了面向读者的形式;中缀形式是短暂的,会在阅读阶段立即被丢弃,取而代之的是用 :lazy-or 标记的等效合法 lisp 形式。

所以我制作了一个几乎可以正常工作的 read 宏,但目前需要在第一个 or-form 关键字元素之前使用一个额外的管道作为一种读者标志(我希望这不是必需的完全),并且它目前无法使用嵌套括号或拼接符号推断类似形式作为等效(如在算术中,2+(3*4)具有相同的运算顺序,等效形式,如2+3*4)。

宏(源自此处的“斜线阅读器”:http : //www.lispworks.com/documentation/HyperSpec/Body/f_rd_rd.htm):

 (defun pipe-reader (stream char)                                                                   
   (declare (ignore char))                                                                          
   `(:lazy-or .  ,(loop for dir = (read stream t nil t)                       
                   then (progn (read-char stream t nil t)                                           
                               (read stream t nil t))                         
                   collect dir                                                                      
                   while (eql …
Run Code Online (Sandbox Code Playgroud)

macros common-lisp infix-notation infix-operator reader-macro

2
推荐指数
1
解决办法
111
查看次数

set-macro-character和set-dispatch-macro-character之间有什么区别?

从这些函数的签名来看,明显的区别在于set-macro-character允许您为单个字符设置reader宏功能,并set-dispatch-macro-character允许您为两个字符的任意组合设置它.这是唯一的区别吗?我什么时候需要使用一个而不是另一个?

common-lisp reader-macro

0
推荐指数
1
解决办法
97
查看次数