Added doc for each bf instruction
This commit is contained in:
parent
9f3b68e23c
commit
80642da476
1 changed files with 82 additions and 11 deletions
93
main.rkt
93
main.rkt
|
@ -18,11 +18,11 @@
|
|||
; Interpretation: a data pointer in the brainf*ck language in a tape.
|
||||
|
||||
; A Program is a String of:
|
||||
; - ">"
|
||||
; - "<"
|
||||
; - "+"
|
||||
; - "-"
|
||||
; - "."
|
||||
; - ">" (tape-right)
|
||||
; - "<" (tape-left)
|
||||
; - "+" (add1)
|
||||
; - "-" (sub1)
|
||||
; - "." (out)
|
||||
; - ","
|
||||
; - "["
|
||||
; - "]"
|
||||
|
@ -34,22 +34,24 @@
|
|||
; A World is a (make-world tape dp output program ip) where:
|
||||
; - tape: Tape
|
||||
; - dp: DataPointer
|
||||
; - tape-len: Nat
|
||||
; - output: String
|
||||
; - program: Program
|
||||
; - ip: InstructionPointer
|
||||
; Interpretation: the current state of execution of a brainf*ck program.
|
||||
(define-struct world [tape dp output program ip])
|
||||
(define-struct world [tape dp tape-len output program ip])
|
||||
|
||||
; Template function for World
|
||||
(define (fn-for-world w)
|
||||
(... (world-tape w)
|
||||
(world-dp w)
|
||||
(world-tape-len w)
|
||||
(world-output w)
|
||||
(world-program w)
|
||||
(world-ip w)))
|
||||
|
||||
; string->program: String -> Program
|
||||
; Given a string, returns a bf program without any invalid character
|
||||
; Given a string, returns a b(world-dp-len w)f program without any invalid character
|
||||
(define (string->program s)
|
||||
(local [; valid-char: 1String -> Boolean
|
||||
; Given a valid-char, returns #t if the character is a valid bf
|
||||
|
@ -85,17 +87,17 @@
|
|||
; program->world: Program -> World
|
||||
; Given a program, returns the corresponding initial world state.
|
||||
(define (program->world p)
|
||||
(make-world (cons 0 '()) 0 "" p 0))
|
||||
(make-world (cons 0 '()) 0 1 "" p 0))
|
||||
|
||||
; Tests for program->world
|
||||
(check-expect (program->world "[->+<]") (make-world (list 0) 0 "" "[->+<]" 0))
|
||||
(check-expect (program->world "[->+<]") (make-world (list 0) 0 1 "" "[->+<]" 0))
|
||||
|
||||
; tape-help: Tape DP (Byte -> Byte) -> Tape
|
||||
; Given a tape and a data pointer, returns the same tape with the data in the
|
||||
; location of the data pointer altered by the function `alter`.
|
||||
(define (tape-help tape dp alter)
|
||||
(cond [(zero? dp) (cons (alter (first tape)) (rest tape))]
|
||||
[else (cons (first tape) (tape-help (rest tape) (sub1 dp)))]))
|
||||
[else (cons (first tape) (tape-help (rest tape) (sub1 dp) alter))]))
|
||||
|
||||
; Tests for tape-help
|
||||
(check-expect (tape-help (list 0) 0 add1-byte) (list 1))
|
||||
|
@ -106,19 +108,88 @@
|
|||
(define (exec-add1 w)
|
||||
(make-world (tape-help (world-tape w) (world-dp w) add1-byte)
|
||||
(world-dp w)
|
||||
(world-tape-len w)
|
||||
(world-output w)
|
||||
(world-program w)
|
||||
(add1 (world-ip w))))
|
||||
|
||||
; exec-sub1: World -> World
|
||||
; Given a world, returns a new world with the + instruction executed
|
||||
; Given a world, returns a new world with the - instruction executed
|
||||
(define (exec-sub1 w)
|
||||
(make-world (tape-help (world-tape w) (world-dp w) sub1-byte)
|
||||
(world-dp w)
|
||||
(world-tape-len w)
|
||||
(world-output w)
|
||||
(world-program w)
|
||||
(add1 (world-ip w))))
|
||||
|
||||
; exec-tape-left: World -> World
|
||||
; Given a world, returns a new world with the < instruction executed
|
||||
(define (exec-tape-left w)
|
||||
(if (zero? (world-dp w))
|
||||
(error "Can't access negative tape positions")
|
||||
(make-world (world-tape w)
|
||||
(sub1 (world-dp w))
|
||||
(world-tape-len w)
|
||||
(world-output w)
|
||||
(world-program w)
|
||||
(add1 (world-ip w)))))
|
||||
|
||||
; exec-tape-right: World -> World
|
||||
; Given a world, returns a new world with the > instruction executed
|
||||
(define (exec-tape-right w)
|
||||
(local [(define end-of-tape (= (world-dp w) (sub1 (world-tape-len w))))]
|
||||
(make-world
|
||||
(if end-of-tape
|
||||
(cons (world-tape w) 0)
|
||||
(world-tape w))
|
||||
(add1 (world-dp w))
|
||||
(if end-of-tape
|
||||
(add1 (world-tape-len w))
|
||||
(world-tape-len w))
|
||||
(world-output w)
|
||||
(world-program w)
|
||||
(add1 (world-ip w)))))
|
||||
|
||||
; exec-out: World -> World
|
||||
; Given a world, returns a new world with the . instruction executed
|
||||
(define (exec-out w)
|
||||
(make-world
|
||||
(world-tape w)
|
||||
(world-dp w)
|
||||
(world-tape-len w)
|
||||
(string-append
|
||||
(world-output w)
|
||||
(list->string
|
||||
(list (integer->char (list-ref (world-tape w) (world-dp w))))))
|
||||
(world-program w)
|
||||
(add1 (world-ip w))))
|
||||
|
||||
; find-first: 1String String Nat -> Nat
|
||||
(define (find-first char string start)
|
||||
(cond [(string=? (substring string start (add1 start)) char) start]
|
||||
[else (find-first char string (add1 start))]))
|
||||
|
||||
; exec-loop-start: World -> World
|
||||
; Given a world, returns a new world with the [ instruction executed
|
||||
(define (exec-loop-start w)
|
||||
(local [(define jump (zero? (list-ref (world-tape w) (world-dp w))))]
|
||||
(make-world
|
||||
(world-tape w)
|
||||
(world-dp w)
|
||||
(world-tape-len w)
|
||||
(world-output w)
|
||||
(world-program w)
|
||||
(add1 (if jump
|
||||
(find-first "]" (world-program w) (world-ip w))
|
||||
(world-ip w))))))
|
||||
|
||||
; Tests for exec-out
|
||||
(check-expect (exec-out (make-world (list 50) 0 1 "" ".[->+<]" 0))
|
||||
(make-world (list 50) 0 1 "2" ".[->+<]" 1))
|
||||
(check-expect (exec-out (make-world (list 65) 0 1 "" ".[->+<]" 0))
|
||||
(make-world (list 65) 0 1 "A" ".[->+<]" 1))
|
||||
|
||||
; main: Filename -> World
|
||||
; Given a Filename, return the last world state of execution of the
|
||||
; corresponding bf program in the file
|
||||
|
|
Loading…
Reference in a new issue