Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Common lisp Brainf**k在Common Lisp中实现_Common Lisp - Fatal编程技术网

Common lisp Brainf**k在Common Lisp中实现

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))

我尝试在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))

(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
    输入
    100
    (我认为这是#\d的ascii码)。我想让它停止评估以等待用户输入,然后继续。有什么简单的方法可以做到这一点吗?@PrzemysławP它可以做到这一点。例如,
    (defun test(),)
    等待运行
    test
    进行输入/输出。但是,如果您只是在REPL中写入
    ,。
    它可能会读取一个点,或者更可能会读取一行,然后轮询输入。在我当前的版本中
    (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)))