-
Notifications
You must be signed in to change notification settings - Fork 0
/
cli.lisp
84 lines (77 loc) · 3.38 KB
/
cli.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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
;;;; cli.lisp
(in-package #:sade)
(defun entry-point ()
(flet ((info (control &rest args)
(apply #'format t control args))
(memp (item list)
(member item list :test #'equalp)))
(let* ((args uiop:*command-line-arguments*)
(argc (length args)))
(handler-case
(cond
((and (= 1 argc) (memp (first args) '("i" "input")))
(loop with collected = ""
while t
for input = (read-line)
when (equal input "")
do (bf-eval-string collected)
and do (setf collected "")
else
do (setf collected (uiop:strcat collected input))))
((and (= 2 argc) (memp (first args) '("o" "optimize")))
(let ((in (uiop:merge-pathnames* (uiop:parse-native-namestring (second args))
(uiop:getcwd))))
(info "The optimized code for ~a is~%~a~%"
in (with-open-file (i in) (bf i)))
(info "~%The optimized assembly for ~a is~%" in)
(let ((name (gensym (string-upcase (pathname-name in)))))
(bf-compile-from-file name in)
(disassemble name))))
((and (<= 2 argc 3) (memp (first args) '("c" "compile")))
(let* ((in (uiop:merge-pathnames* (uiop:parse-native-namestring (second args))
(uiop:getcwd)))
(out (uiop:merge-pathnames*
(or (uiop:parse-native-namestring (third args)) (pathname-name in))
(uiop:getcwd))))
#+ecl
(uiop:with-temporary-file
(:stream f :pathname p :type "lisp" :keep t)
(print (with-open-file (i in) (bf i)) f)
(print '(si:quit) f)
:close-stream
(compile-file p :system-p t)
(c:build-program
out :lisp-files (list (uiop:merge-pathnames*
(concatenate 'string (pathname-name p) ".o") p))))
#-ecl
(let ((tmpname (gensym "TMP")))
(bf-compile-from-file tmpname in)
(setf uiop:*image-entry-point* (lambda () (funcall tmpname)))
(uiop:dump-image out :executable t))))
((or (zerop argc) (memp args '(("h") ("-h") ("help") ("--help"))))
(info "Sade, an extensible Brainfuck to Lisp compiler.
Usage: sade command [args]
Commands~13tArgs~25tDescription
~2th/help~25tprint this message.
~2to/optimize~13tin~25tshow the optimized code for IN.
~2tc/compile~13tin [out]~25tcompile IN into OUT.
~2ti/input~25tstart an interactive BF shell.
Examples:
# compile hello.bf to hello
sade c hello.bf hello
# the same thing, yet shorter
sade c hello.bf
# run the previously compiled hello
./hello"))
(t (info "No such command found. Try
sade h
to know the commands there are.~%")))
(#+sbcl sb-sys:interactive-interrupt
#+ccl ccl:interrupt-signal-condition
#+clisp system::simple-interrupt-condition
#+ecl ext:interactive-interrupt
#+allegro excl:interrupt-signal
()
(info "Interrupt received. Quitting...~%")
(uiop:shell-boolean-exit nil)))))
(uiop:shell-boolean-exit t))