diff --git a/README.md b/README.md index e2c027e..911fd3f 100644 --- a/README.md +++ b/README.md @@ -7,19 +7,29 @@ _Tommaso Rodolfo Masera_. Run the file `gui.rkt` using *DrRacket* or the `racket` CLI tool. +A CLI version of the interpreter is avaliable. In order to run it, execute: + +`./cli.rkt ` + +More documentation of this command is avaliable using the `-h` flag. + ## Current features - Brainf\*ck interpreter works for the instructions `[`, `]` `+`, `-`, `<`, `>` - , `.`; + , `.`, ','; - Done simple editor GUI with *Run* button and output window. - Editor supports basic syntax highlighting. ## Bugs -- `,` function not implemented (will crash the program if encountered); - No validation or user-friendly error handling. ## Feedback -Add documentation about the language for someone that doesn't know it. How does it work? What are the instructions? What do they do? Example programs? -In your "running" section explain how to run the interpreter without the GUI. +### Add documentation about the language for someone that doesn't know it. How does it work? What are the instructions? What do they do? Example programs? + +WIP + +### In your "running" section explain how to run the interpreter without the GUI. + +Done with `cli.rkt`. diff --git a/cli.rkt b/cli.rkt new file mode 100755 index 0000000..dbfcf39 --- /dev/null +++ b/cli.rkt @@ -0,0 +1,66 @@ +#! /usr/bin/env racket +#lang racket + +(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 (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)