Common lisp Brainf**k在Common Lisp中实现
我尝试在Common Lisp、SBCL中实现Brainf**k。我遇到了一些问题Common lisp Brainf**k在Common Lisp中实现,common-lisp,Common Lisp,我尝试在Common Lisp、SBCL中实现Brainf**k。我遇到了一些问题 (defparameter *tape* (make-array '(1) :adjustable t)) (defparameter *pointer* 0) (defparameter *tape-size* 1) (defparameter *output* (make-array '(0) :element-type 'base-char :fill-pointer 0 :adjustable t))
(defparameter *tape* (make-array '(1) :adjustable t))
(defparameter *pointer* 0)
(defparameter *tape-size* 1)
(defparameter *output* (make-array '(0) :element-type 'base-char :fill-pointer 0 :adjustable t))
(defun move-pointer-right (a b)
(declare (ignore a))
(declare (ignore b))
'(progn
(incf *tape-size*)
(adjust-array *tape* (list *tape-size*))
(incf *pointer*)))
(defun move-pointer-left (a b)
(declare (ignore a))
(declare (ignore b))
'(progn (decf *pointer*)))
(defun increment-byte (a b)
(declare (ignore a))
(declare (ignore b))
'(incf (aref *tape* *pointer*)))
(defun decrement-byte (a b)
(declare (ignore a))
(declare (ignore b))
'(decf (aref *tape* *pointer*)))
(defun start-loop (stream ch)
(declare (ignore ch))
(let ((loop-body (read-delimited-list #\] stream t)))
`(loop :until (zerop (aref *tape* *pointer*))
:do ,@loop-body)))
(defun print-one-char (a b)
(declare (ignore a))
(declare (ignore b))
'(with-output-to-string (s *output*) (write-char (code-char (aref *tape* *pointer*)) s)))
(defun read-one-char (a b)
(declare (ignore a))
(declare (ignore b))
'(setf (aref *tape* *pointer*) (char-code (read-char *standard-input*))))
(defun flush-output (a b)
(declare (ignore a))
(declare (ignore b))
'(progn *output*))
(defun reset-me (a b)
(declare (ignore a))
(declare (ignore b))
'(progn
(setf *output* (make-array '(0) :element-type 'base-char :fill-pointer 0 :adjustable t))
(adjust-array *tape* '(1))
(setf (aref *tape* 0) 0)
(setf *pointer* 0)))
(set-macro-character #\< #'move-pointer-left)
(set-macro-character #\> #'move-pointer-right)
(set-macro-character #\+ #'increment-byte)
(set-macro-character #\[ #'start-loop)
(set-macro-character #\= #'flush-output)
(set-macro-character #\. #'print-one-char)
(set-macro-character #\, #'read-one-char)
(set-macro-character #\! #'reset-me)
(set-macro-character #\- #'decrement-byte)
(定义参数*磁带*(制作阵列(1):可调t))
(defparameter*指针*0)
(defparameter*磁带大小*1)
(defparameter*输出*(生成数组’(0):元素类型“基本字符:填充指针0:可调t))
(将指针向右移动(a和b)
(声明(忽略a))
(声明(忽略b))
"(progn)
(增量*磁带大小*)
(调整阵列*磁带*(列表*磁带大小*)
(incf*指针*))
(将指针向左移动(a和b)
(声明(忽略a))
(声明(忽略b))
'(progn(decf*指针*))
(定义增量字节(a b)
(声明(忽略a))
(声明(忽略b))
'(incf(aref*磁带**指针*))
(减排量字节(a b)
(声明(忽略a))
(声明(忽略b))
'(decf(aref*磁带**指针*))
(卸载启动回路(流ch)
(声明(忽略ch))
(let((循环体(读取分隔列表\\]stream t)))
`(循环:直到(zerop(aref*磁带**指针*))
:do,@loop body)))
(取消打印一个字符(a b)
(声明(忽略a))
(声明(忽略b))
'(输出为字符串(s*输出*)(写入字符(代码字符(aref*磁带**指针*)s)))
(defun读取一个字符(a b)
(声明(忽略a))
(声明(忽略b))
'(setf(aref*磁带**指针*)(字符代码(读取字符*标准输入*))
(除油冲洗输出(a b)
(声明(忽略a))
(声明(忽略b))
'(程序*输出*)
(卸载重置me(a b)
(声明(忽略a))
(声明(忽略b))
"(progn)
(setf*输出*(生成数组(0):元素类型“基本字符:填充指针0:可调t))
(调整阵列*磁带*'(1))
(setf(aref*磁带*0)0)
(setf*指针*0)))
(设置宏字符“向左移动指针”)
(设置宏字符#\>#移动指针向右移动)
(设置宏字符增量字节)
(设置宏字符“开始循环”)
(设置宏字符#\=#'刷新输出)
(设置宏字符“打印一字符”)
(设置宏字符#\,#“只读一字符”)
(设置宏字符#\!#'重置-me)
(设置宏字符减量字节)
- 输入不起作用
- 我不确定嵌套循环是否可以工作,因为“[”读取“]”,如果您尝试“[/commands[/more]/dubious]”,我不知道如何使用此方法加载/dubious
- 我尝试了“++[->++>+,但不太了解它的工作原理。您需要将
、磁带
和指针
定义为全局变量,最好使用输出
,这样您就可以看到它们是全局变量*耳罩*
(defparameter *tape* (make-array '(1) :adjustable t))
然后我注意到
使用默认元素
扩展了nil
。因此,对于每个*磁带*
,如果它不是真的,您应该将它设置为0(除了
,每个值都是真的)它似乎还认为nil
指针总是在磁带的末尾。在做
>>+++++谢谢你!我编辑了这个问题。现在除了输入之外,一切都正常了。至于输入:
输入,d
(我认为这是#\d的ascii码)。我想让它停止评估以等待用户输入,然后继续。有什么简单的方法可以做到这一点吗?@PrzemysławP它可以做到这一点。例如,100
等待运行(defun test(),)
进行输入/输出。但是,如果您只是在REPL中写入test
它可能会读取一个点,或者更可能会读取一行,然后轮询输入。在我当前的版本中,。
不会编译。“列表中的后面不会显示任何内容。”“。我将尝试重新定义(defun test(),)
,或者放弃并接受暂时不输入。无论如何,再次感谢您。”。读取一个字符
(defun start-loop (stream ch) (declare (ignore ch)) (let ((loop-body (read-delimited-list #\] stream t))) `(loop :until (zerop (aref *tape* *pointer*)) :do ,@loop-body)))
(defun move-pointer-left () (assert (> *pointer* 0) (*pointer*) "Tape pointer out of bounds: ~a" *pointer*) (decf *pointer*)) (set-macro-character #\< (constantly '(move-pointer-left)))