DrBrainf-ck/src/cli.rkt

71 lines
2.1 KiB
Racket
Executable File

#! /usr/bin/env racket
#lang racket
; vim: set tw=80 :
(require "interpreter.rkt"
racket/block)
(define is-program (make-parameter #f))
(define show-tape (make-parameter #f))
; Init flags and argument from cli
(define file-or-program
(command-line
#:program
"bfrkt"
#:once-each
[("-p" "--program") "Interpret the argument as a program,"
"not as a filename"
(is-program #t)]
[("-t" "--tape") "Display trace of program state at the end of execution"
(show-tape #t)]
#:args (arg)
arg))
; The program to execute
(define program
(string->program
(if (is-program)
; Set program to file-or-program if `-p` is set
file-or-program
; Otherwise parse the contents of the file whose name is file-or-program
(file->string file-or-program #:mode 'text))))
; end-print: ProgState -> ()
; Given the fineal prog-state, prints the results according to the flags.
(define (end-print p)
(display (prog-state-output p))
(if (eq? (prog-state-error p) #f)
(display (string-append "\n" (prog-state-error p)))
(void))
(if (show-tape) (display-status p) (void)))
; display-trace: ProgState -> _
; Given a prog-state, prints a trace of it to stdout.
(define (display-status p)
(define t (prog-state-tape p))
(define dp (prog-state-dp p))
(display "######")
(display "\nTape: ")
(display (foldr (lambda (x y) (string-append x " " y))
""
(map (lambda (x) (number->string x)) t)))
(display "\nData pointer: ")
(display dp)
(display "\n######"))
; execute-cli: Program -> ()
; Executers the program in `program` reading and writing respectively from
; stdin and stdout.
(define (execute-cli program)
(execute (program->prog-state program)
end-print
(lambda (call)
(display "Input a character: ")
(define data-read (read-line (current-input-port) 'any))
(if (eof-object? data-read)
(call 0)
(call (char->integer (string-ref data-read 0)))))))
(execute-cli program)