在Common Lisp HyperSpec页面上unread-char- 请参阅
此处 - 它说明了以下两点:
"unread-char旨在成为允许Lisp读者和其他解析器在输入流中执行单字符预测的有效机制."
"在同一个流上连续两次调用unread-char是错误的,而没有在该流上调用read-char(或其他隐式读取字符的输入操作)."
我正在研究如何为我正计划编写的解析器添加对CL流的多字符前瞻支持,并且为了确认上述内容,我运行了以下代码:
(defun unread-char-test (data)
(with-input-from-string (stream data)
(let ((stack nil))
(loop
for c = (read-char stream nil)
while c
do (push c stack))
(loop
for c = (pop stack)
while c
do (unread-char c stream)))
(coerce
(loop
for c = (read-char stream nil)
while c
collect c)
'string)))
(unread-char-test "hello")
==> "hello"
Run Code Online (Sandbox Code Playgroud)
它没有抛出错误(在SBCL或CCL上,我还没有在其他实现上测试它)但我没有看到可能有任何读取操作(隐式或显式)发生在流之间连续打电话给unread-char.
这种行为对于多字符前瞻来说是好消息,只要它是一致的,但为什么不抛出错误?
我知道def*可以有docstrings,所以我只是尝试一下lambdas.
令人尴尬的是,以下内容返回NIL.
(documentation (lambda () "a function which always returns nil" nil) 'function)
Run Code Online (Sandbox Code Playgroud)
怎么了?lambdas不能有docstrings吗?有办法吗?
我有一个函数在Windows上读取一个文本文件(因此一个CRLF作为行结尾的文件),当我在这个文件上调用read-line时,我得到以CR结尾的字符串,这是用SBCL或Clozure CL.使用MKCL,CR和LF都被删除了.
所以我想知道,哪种实施是正确的?
根据标准,主要值line是读取的行,表示为字符串(没有尾随换行符,如果有的话).(见这里).因此,我认为应该没有CR或LF,但对我来说不是很清楚.
当然,有一些解决方法,但它很烦人,我想知道它是一个错误,还是仅仅依赖于实现.
所以我正在编写自己的函数,我调用了它make-list,我从调试器得到了这个:
The function MAKE-LIST is predefined in Clozure CL.
[Condition of type SIMPLE-ERROR]
Restarts:
0: [CONTINUE] Replace the definition of MAKE-LIST.
Run Code Online (Sandbox Code Playgroud)
很好,但如果我不小心选择了选项怎么办0?我的编译器是否会被破坏并且永远有一个错误的内部函数定义,因为我会替换它?
在CCL顶级,运行:
(make-socket :LOCAL-PORT 6666 :LOCAL-HOST "127.0.0.1")
Run Code Online (Sandbox Code Playgroud)
要么
(make-socket :LOCAL-PORT 6666 :LOCAL-HOST (lookup-hostname "localhost"))
Run Code Online (Sandbox Code Playgroud)
输出以下内容:
> Error: There is no applicable method for the generic function:
> #<STANDARD-GENERIC-FUNCTION CCL::SOCKADDR #x30200043F91F>
> when called with arguments:
> (NIL)
> While executing: #<CCL::STANDARD-KERNEL-METHOD NO-APPLICABLE-METHOD (T)>, in process listener(1).
> Type :GO to continue, :POP to abort, :R for a list of available restarts.
> If continued: Try calling it again
> Type :? for other options.
Run Code Online (Sandbox Code Playgroud)
我无法理解错误(CL的新内容).这是什么意思?我做错了什么?
我想枚举我的Lisp进程中可用的所有环境变量的列表.我想要C变量返回的相同列表environ.
SBCL和Clozure CL似乎都没有开箱即用.我可以用CFFI做吗?
在Clozure Common Lisp中调用(file-exists -p"somepath")时,我得到一个"未定义的函数FILE-EXISTS-P with arguments ..."错误,但在任何地方我看起来这个函数都应该可用.我甚至在使用Mx apropos时都会看到它.
我正在使用LispBox for Windows.
有没有人知道可能出现什么问题,或者可能建议我可以尝试解决这个问题的过程?
我还有一个关于在Common Lisp中解码JSON的问题.我决定采用ST-JSON我的工具.我能够获得一个JSO包含JSON数据的对象,并访问所有字段st-json:getjso.我想编写一个原则上类似于宏的宏来destructuring-bind提供对JSON字段之后命名的变量的局部绑定(从那以后我开始怀疑这是不是一个好主意,但这是一个不同的问题).我想出了以下内容:
(defmacro destructure-jso (jso &body body)
(let (keys values)
(st-json:mapjso #'(lambda (key value)
(push key keys)
(push value values))
jso)
`(destructuring-bind ,keys ,values
,@body)))
Run Code Online (Sandbox Code Playgroud)
但是当我尝试在JSO对象上使用它时,我得到的错误The value PARAMS is not of the expected type STRUCTURE.在哪里PARAMS是对象.谁可以给我解释一下这个?
谢谢.
我试图永久地将stdout重定向到一个文件,但我可以找到关于这样做的所有示例都涉及使用标准输出全局在let或内部打开文件中执行此操作.有没有办法可以进行应用程序范围的重定向?
编辑:这是我尝试使用标准输出重定向的方式:
(Setf *log* (open "/Users/Mike/Desktop/some.txt" :direction :output :if-exists :append))
(Setf *standard-output* *log*)
(print "Test")
Run Code Online (Sandbox Code Playgroud)
这会停止输出到REPL,但是没有任何内容显示在probe-file打印调用中的文件中(确实存在并且可以看到).
编辑:我尝试使用Dribble功能:
(Dribble "/Users/Mike/Desktop/some.txt")
(format t "hello")
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误:
错误:通用函数没有适用的方法:#STANDARD-GENERIC-FUNCTION CCL :: STREAM-SET-COLUMN#x30200006557F用参数调用时:(#0)执行:#时,在进程Listener(11)中.键入cmd- /继续,cmd-.要中止,cmd- \以获取可用重新启动的列表.如果继续:尝试再次调用类型:?其他选择.
在一个CCL REPL中,我输入:
(WITH-OPEN-SOCKET (socket :LOCAL-PORT 6667
:LOCAL-HOST "localhost"
:CONNECT :PASSIVE
:REUSE-ADDRESS t)
(let ((stream (ACCEPT-CONNECTION socket :wait t)))
(format stream "hello from server.~%")))
Run Code Online (Sandbox Code Playgroud)
它等待连接.
在另一个CCL流程中,我输入:
(WITH-OPEN-SOCKET (socket-stream :REMOTE-PORT 6667
:REMOTE-HOST "localhost"
:CONNECT :ACTIVE
:REUSE-ADDRESS t)
(format t (READ-LINE socket-stream)))
Run Code Online (Sandbox Code Playgroud)
此时此过程进入等待状态.它既不从服务器读取也不退出.
但是,当客户端连接到服务器时,服务器将以NIL退出.很明显,至少建立了一个连接,但字符串"Hello from server".永远不会沟通.
我相信这是我忽略的基本内容.如何发送消息?READ-LINE不是从流中读取的正确方法吗?我从服务器上写错了吗?如何建立基于双向简单字符串的通信?
我有:
(defmacro assign (name value)
(format t "assigning ~A to ~A~%" `,name `,value))
(defun opcode-call (&rest args)
(mapcar (lambda (arg)
(if (stringp arg)
(let ((var (gensym)))
(assign var arg)
var)
arg))
args))
Run Code Online (Sandbox Code Playgroud)
当我编译操作码调用时,REPL输出:
assigning VAR to ARG
OPCODE-CALL
Run Code Online (Sandbox Code Playgroud)
为什么在编译时对赋值进行求值?
ccl ×11
common-lisp ×11
lisp ×6
sbcl ×3
sockets ×2
buffered ×1
cffi ×1
clozure-cl ×1
io ×1
json ×1
lisp-macros ×1
macros ×1
newline ×1
stdout ×1
stream ×1