#! /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)