Brainf ** k를 Common Lisp, SBCL로 구현하려고했습니다. 나는 몇 가지 문제를 겪었다.Brainf ** k가 Common Lisp에서 구현되었습니다.
(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)
- 입력 내가 중첩 루프 때문에 일하는 것이 있는지 확실하지 않다
- 작동하지 않습니다 "["를 읽고에 "]"당신이하려고하면 "[/ 명령 [/ 더]/반신 반의] "나는이 방법으로 얼마나/모호한 것이 될지 짐작할 수 없다.
- "++ [-> +> + < <]"시도했습니다. 내가 아는 한 배열에는 "0 2 2"가 있어야하지만 대신 "0 2 0"이 있습니다. 나는 뭔가 잘못되었다고 결론을 내린다.
- 나는 SBCL로부터 많은 경고를 받고있다. 그럴 필요가 없다 :/
- "move-pointer-right"와 같은 함수에서 리턴 된 모든 생성 된 코드를 빠르게 출력 할 수 있는가? 파일로?
- 출력은 "="명령에서 인쇄 할 하나의 문자열로 저장됩니다. 나는 다른 작업들이 많은 쓸모없는 것을 표준 출력에 인쇄했기 때문에 그것을했다. 나에게 큰 문제는 아니며,이 해결 방법 대신 단순히 파일로 인쇄하는 것을 상상하기 쉽습니다.
- 영어로 실수를해서 유감입니다.
편집 : 코드를 편집했습니다 (다시 도움 주셔서 감사합니다, Sylwester). 입력을 제외한 모든 것이 작동하는 것 같습니다.
입력에 관해서는 : 나는
read-char
을 사용하지만, 내가 원하는 방식으로 작동하지 않습니다. 예를 들어,D
은 "D"를 입력합니다. 다시 실행하여 각,
에서 평가를 중단하고 사용자 입력을 기다립니다.질문 : 값을 반환하지 않습니다
progn
에 대한 대안은 (난 그냥하지만 반환하지 평가하려는)이 있습니까? 예를 들어(what-i-look-for (setf a 1) 1 2)
1
에a
을 설정하지만, 그래서*earmuffs*
으로 양호하게는, 당신은 당신이 전역 변수로tape
,pointer
및output
를 정의 할 필요가 작동하는데 어떻게 생각하는지에 대해 너무 많이 알고하지 않고 2
대단히 감사합니다. 나는 질문을 편집했다. 입력을 제외한 모든 것이 이제는 작동하는 것 같습니다. 입력에 관해서 :'d '는'100'을 입력합니다 (이것은 # \ d에 대한 ASCII 코드입니다). ** 사용자 입력을 기다린 다음 평가를 계속 ** 평가를 중단하고 싶습니다. 이 작업을 수행하는 쉬운 방법이 있습니까? –
@ PrzemysławP 그건 그렇습니다. 예. '(defun test(),.,.,.)'는 입출력을하기 위해'test'를 실행할 때까지 기다립니다. 그러나', .'을 REPL에 쓰면 점을 읽거나 더 많은 행을 읽고 입력을 폴링 할 가능성이 있습니다. – Sylwester
현재 버전'(defun test(),.)'에서는 컴파일되지 않습니다. "목록에 아무것도 표시되지 않습니다." 나는'read-one-char'을 재정의하거나 지금은 입력을 포기하고 받아들이지 않을 것입니다. 어쨌든 다시 한번 감사드립니다. –