UNB/ CS/ David Bremner/ teaching/ cs4613/ tutorials/ CS4613 Tutorial 10: Practice for Final

Dynamic Scope Call

Complete the given interp function to support a variant appDynE to call a function with dynamic rather lexical scope.

The following two tests contrast the lexically scoped appE with the dynamically scoped appDynE.

(module+ test
  (define (example body)
    (let1E 'x (numE 3)
           (let1E 'f (lamE 'y (plusE (varE 'x) (varE 'y)))
                  (let1E 'x (numE 5)
                         body))))

  (test (interp (example (appE (varE 'f) (numE 4))) mt-env)
        (numV 7))

  (test (interp
         (example (appDynE (varE 'f) (numE 4))) mt-env)
        (numV 9))

  (test (interp
         (example
          (let1E 'f (lamE 'x (varE 'x))
                 (appDynE (varE 'f) (numE 4))))
         mt-env)
        (numV 4))

  (test (interp
         (example
          (let1E 'f (lamE 'y (varE 'x))
                 (appDynE (varE 'f) (numE 4))))
         mt-env)
        (numV 5))

  (test (interp
         (example
          (let1E 'f (lamE 'y (varE 'x))
                 (let1E 'x (numE 3)
                        (appDynE (varE 'f) (numE 4)))))
         mt-env)
        (numV 3))

  (test/exn (interp (appE (varE 'g) (numE 4)) mt-env) "not bound")
  (test/exn (interp (example (appE (numE 4) (varE 'f))) mt-env) "function")
  (test/exn (interp (example (appDynE (numE 4) (varE 'f))) mt-env) "function")
  )

Combining GC passes

Below you are given a partial implementation of a plai/gc2 style collector for a simple heap with no freelist or bitmap in the style of Lecture 20. Unlike there, in this question you are asked to combine the phase of marking white with that of freeing any records previously marked white.

We will revisit these ideas in Lecture 23; you may find it helpful to read ahead.

Complete the function free/mark-white! so that the given tests pass.

Note:

(module+ test
  (with-heap (make-vector 7 '?)
    (init-allocator)
    (test (current-heap) (make-vector 7 'free))
    (gc:alloc-flat 'first)
    (test (current-heap) #(flat first free free free free free))
    (gc:alloc-flat 'rest)
    (test (current-heap) #(flat first flat rest free free free))
    (gc:cons 0 2)
    (test (current-heap) #(flat first flat rest cons 0 2))
    (free/mark-white!)
    (test (current-heap) #(white-flat first white-flat rest white-cons 0 2))
    (free/mark-white!)
    (test (current-heap)  (make-vector 7 'free))
    (gc:alloc-flat 'first)
    (gc:alloc-flat 'rest)
    (gc:cons 0 2)
    (free/mark-white!)
    (test (current-heap) #(white-flat first white-flat rest white-cons 0 2))
    )

  (with-heap  (vector 'flat 'first 'flat 'rest 'white-cons 0 2)
    (free/mark-white!)
    (test (current-heap) #(white-flat first white-flat rest free free free))
    (heap-set! 0 'flat)
    (free/mark-white!)
    (test (current-heap) #(white-flat first free free free free free)))

  (with-heap (make-vector 5 #f)
    (init-allocator)
    (gc:cons 0 0)
    (test (current-heap) #(cons 0 0 free free))
    (malloc 2)
    (test/exn (malloc 100) "out of memory")
    (heap-set! 0 'fail)
    (test/exn (malloc 2) "unexpected tag"))
  )