-
Notifications
You must be signed in to change notification settings - Fork 3
/
brainfuck.lisp
63 lines (60 loc) · 2.73 KB
/
brainfuck.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
(require 'asdf)
(defpackage #:brainfuck
(:use #:cl #:uiop))
(in-package #:brainfuck)
(declaim (optimize (speed 3) (debug 0)))
(defun file-string (path)
(with-open-file (stream path)
(let ((data (make-string (file-length stream))))
(read-sequence data stream)
data)))
(labels
((retrieve-left (code index amount)
(if (= amount 0)
(+ index 1)
(let ((c (char code (- index 1))))
(if (string= c "[")
(retrieve-left code (- index 1)(- amount 1))
(if (string= c "]")
(retrieve-left code (- index 1)(+ amount 1))
(retrieve-left code (- index 1) amount))))))
(retrieve-right (code index amount)
(if (= amount 0)
index
(let ((c (char code (+ index 1))))
(if (string= c "]")
(retrieve-right code (+ index 1)(- amount 1))
(if (string= c "[")
(retrieve-right code (+ index 1)(+ amount 1))
(retrieve-right code (+ index 1) amount))))))
(run-bf (code iptr data dptr len)
(when (not (= iptr len))
(let ((c (char code iptr)))
(cond
((char= c #\>)
(run-bf code (+ iptr 1) data (+ dptr 1) len))
((char= c #\<)
(run-bf code (+ iptr 1) data (- dptr 1) len))
((char= c #\+)
(incf (nth dptr data))
(run-bf code (+ iptr 1) data dptr len))
((char= c #\-)
(decf (nth dptr data))
(run-bf code (+ iptr 1) data dptr len))
((char= c #\.)
(format *STANDARD-OUTPUT* "~A" (code-char (nth dptr data)))
(run-bf code (+ iptr 1) data dptr len))
((char= c #\,)
(setf (nth dptr data) (char-code (read-char)))
(run-bf code (+ iptr 1) data dptr len))
((string= c "[")
(if (= (nth dptr data) 0)
(run-bf code (retrieve-right code iptr 1) data dptr len)
(run-bf code (+ iptr 1) data dptr len)))
((string= c "]")
(if (not (= (nth dptr data) 0))
(run-bf code (retrieve-left code (- iptr 1) 1) data dptr len)
(run-bf code (+ iptr 1) data dptr len))))))))
(let ((code (file-string (nth 0 uiop:*command-line-arguments*))))
(run-bf code 0 (make-list 30000 :initial-element 0) 0 (length code))
(uiop:quit)))