Execute Brain****/Common Lisp: Difference between revisions
m
Fixed syntax highlighting.
(Added proper catagory setting) |
m (Fixed syntax highlighting.) |
||
(11 intermediate revisions by 9 users not shown) | |||
Line 1:
{{implementation|Brainf***}}{{collection|RCBF}}
This is an implementation of [[Brainf***]] written in [[Common Lisp]].
(program)▼
<syntaxhighlight lang="lisp">(defstruct bf-state
(memory (make-array 1 :initial-element 0 :adjustable t))▼
(stack))
(defmacro with-bf-slots ((program-sym program-counter-sym
obj-expr &body body)
"Macro to replace cumbersome structure slot references with
local lexical macros resembling local variables."
`(symbol-macrolet ((,program-sym (bf-state-program ,obj-expr))
,@body))
(defun adjust-memory (state)
"Modifies memory and memory-pointer such that memory-pointer is
a valid index to the memory array. If it is too large, the array
is extended; if it is negative, the array is extended, its
contents are shifted forward and the memory-pointer is incremented,
by an amount to make the memory ."
(with-bf-slots (program pc mem ptr stack) state
(cond ((>= ptr (length mem))
(adjust-array mem (1+ ptr) :initial-element 0))
(let ((extent (- ptr)))
(setf mem (make-array (+ (length old-memory) extent)))
(setf (subseq mem extent) old-memory)))))))
(loop with depth = 1
▲ (cond ((>= (bf-state-memory-pointer state)
for index
do (error "unmatched [ bracket")
▲ (1+ (bf-state-memory-pointer state))
do (case (aref program
(
▲ (setf (bf-state-memory state)
▲ (make-array (+ (length old-memory) extent)))
▲ (setf (subseq (bf-state-memory state) extent)
▲ old-memory))))))
(with-bf-slots (program pc mem ptr stack) state
(#\+ (incf (aref mem
(#\> (incf
(#\[ (if (/=
(#\] (setf pc (pop stack)))
(#\. (write-char (code-char (aref mem ptr)) stream)))
▲ (defun brainfuck-eval (state &optional (stream *standard-output*))
▲ (places nil))
(defun brainfuck-compile-guts (program &optional (start 0) (until-bracket nil))
(loop for insn from start
appending (case (aref program insn)
▲ (#\+ (incf (elt (bf-state-memory state) (bf-state-memory-pointer state))))
(#\
(#\
(#\
(
(#\] (if
(loop-finish)
▲ (incf (bf-state-program-counter state)))))
(error "internal problem matching brackets"))
(error "extra ] bracket")))
(defun bf (program) (brainfuck-eval (make-bf-state :program program)))▼
(#\. `((write-char (code-char (aref mem ptr)) stream))))))
(defun brainfuck-compile (program)
(compile nil `(lambda (&optional (stream *standard-output*))
(let ((state (make-bf-state :program ,program)))
(with-bf-slots (program pc mem ptr stack) state
,@(brainfuck-compile-guts program))
(values)))))
(defun bf (program)
(if (and (not (zerop (length program)))
(char= #\! (aref program 0)))
(funcall (brainfuck-compile program))
"read-eval-print loop for bf. Code prefixed with ! is compiled, otherwise interpreted"
▲ (princ "BRAINFUCK> ")
(bf (read-line))))</syntaxhighlight>
|