Skip to content

Commit 9faccfc

Browse files
committed
lab6 solutions
1 parent a930f7c commit 9faccfc

1 file changed

Lines changed: 79 additions & 2 deletions

File tree

labs/lab06.md

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ consisting of numbers 1,2,3,4,5,6,7 with 4 being the active number.
8383
(move 'right t) => '(tape (4 3 2 1) 5 (6 7))
8484
```
8585

86-
<!--
8786
::: details Solution
8887
```racket
8988
(define (change op t)
@@ -101,7 +100,6 @@ consisting of numbers 1,2,3,4,5,6,7 with 4 being the active number.
101100
     (tape (cons val left) (car right) (cdr right))]))
102101
```
103102
:::
104-
-->
105103

106104
## Task 2
107105
Modify the implementation of the interpreter from the lecture so that it uses your purely functional tape.
@@ -204,6 +202,85 @@ For your convenience, my complete implementation is shown below.
204202
```
205203
:::
206204

205+
::: details Final solution
206+
```racket
207+
#lang racket
208+
209+
;;; Task 1 - make purely functional tape
210+
(struct tape (left val right) #:transparent)
211+
212+
(define (fresh-tape size)
213+
(tape '() 0 (make-list (- size 1) 0)))
214+
215+
(define (change op t)
216+
(tape (tape-left t)
217+
(op (tape-val t) 1)
218+
(tape-right t)))
219+
220+
(define (move dir t)
221+
(match (cons dir t)
222+
[(cons 'left (tape '() _ _)) (error "Outside tape")]
223+
[(cons 'right (tape _ _ '())) (error "Outside tape")]
224+
[(cons 'left (tape left val right)) (tape (cdr left) (car left) (cons val right))]
225+
[(cons 'right (tape left val right)) (tape (cons val left) (car right) (cdr right))]))
226+
227+
;;; Task 2 - modify the interpreter of Brainf*ck from the lecture to be purely functional
228+
; Sample program adding two numbers
229+
(define add-prg
230+
'(@ > @ [- < + >] < *)
231+
)
232+
233+
; Sample program multiplying two numbers
234+
(define mul-prg
235+
'(@ > @ < [- > [- > + > + < <] > [- < + >] < <] > > > *)
236+
)
237+
238+
; constant for the size of the tape
239+
(define SIZE 10)
240+
241+
(define (eval-comma prg input t)
242+
(define new-tape
243+
(match (cons input t)
244+
[(cons '() _) (error "Empty input")]
245+
[(cons (list val z ...) (tape left _ right)) (tape left val right)]))
246+
(eval-prg prg (cdr input) new-tape))
247+
248+
(define (eval-cmd cmd prg input t)
249+
(let ([new-t
250+
(match cmd
251+
['+ (change + t)]
252+
['- (change - t)]
253+
['< (move 'left t)]
254+
['> (move 'right t)]
255+
['* (printf "~a " (tape-val t)) t]
256+
[_ (error "Unknown command")])])
257+
(eval-prg prg input new-t)))
258+
259+
(define (eval-cycle cycle prg input t)
260+
(if (= (tape-val t) 0)
261+
(eval-prg prg input t)
262+
(begin
263+
(let* ([cycle-result (eval-prg cycle input t)]
264+
[new-input (car cycle-result)]
265+
[new-t (cadr cycle-result)])
266+
(eval-cycle cycle prg new-input new-t)))))
267+
268+
(define (eval-prg prg input t)
269+
(displayln t)
270+
(match prg
271+
[(list) (list input t)]
272+
[(list '@ rest ...) (eval-comma rest input t)]
273+
[(list (? list? cmd) rest ...) (eval-cycle cmd rest input t)]
274+
[(list cmd rest ...) (eval-cmd cmd rest input t)]))
275+
276+
(define (run-prg prg input)
277+
(eval-prg prg input (fresh-tape SIZE))
278+
(printf "done~n"))
279+
280+
(run-prg add-prg '(12 5))
281+
```
282+
:::
283+
207284
<!--
208285
/*
209286
A solution to Task 2 can be found [[https://drive.google.com/file/d/1tPR3ZxEop3l7qmHoywekLTuc7KhwgS_x/view?usp=sharing|here]].

0 commit comments

Comments
 (0)