Section notes: Week 9

CS 164, Fall 2005

General

Warm-up

In C-style array initializers, commas can serve to separate items or to end items; for example, I could write

    int foo[3] = {0,1,2};
    int bar[3] = {0,1,2,};
  
The latter form is useful for long lists, either computer-generated or human-maintained, which must change from time to time.

MJ data structures

(defstruct mj-env
  stdout   ; standard output stream
  stderr   ; error output stream
  parents  ; class-name -> parent class-name assoc
  classes  ; class-name -> class layout hash
  methods  ; (class-name . method-name) -> method info hash
  stack)   ; Run-time stack

(defstruct mj-method
  class       ; Name of this class (for setting 'this' type)
  name        ; Method name
  formals     ; Formal parameter list (as an (id . type) assoc list)
  layout      ; Stack frame layout
  code        ; Statement list
  type        ; Return value type
  value)      ; Return value expression

;; Variable layouts are hash tables with
;;   *count* -> current number of variables
;;   name    -> stack of (index . type) pairs

Dynamic dispatch: take 2

class Week9 {
    public static void main(String[] a) {
         System.out.println(new Counter().Init(1).Next());
    }
}

class Counter {
    int count;
    public Counter Init(int c) { count = c; return this; }
    public int     Next()      { count = count + 1; return count; }
}

;; === Translated from ../notes/week9 ===
(unless (boundp '*mj-stdout*) (setf *mj-stdout* t))

;; Counter::Init
(DEFUN |mjl-Counter-Init| (THIS L1) (LET () (SETF (ELT THIS 1) L1) THIS))

;; Counter::Next
(DEFUN |mjl-Counter-Next| (THIS)
  (LET () (SETF (ELT THIS 1) (+ (ELT THIS 1) 1)) (ELT THIS 1)))

;; Vtable for Counter
(SETF |mjl-Counter| (MAKE-HASH-TABLE))
(SETF (GETHASH '|Next| |mjl-Counter|) #'|mjl-Counter-Next|)
(SETF (GETHASH '|Init| |mjl-Counter|) #'|mjl-Counter-Init|)

;; Constructor for Counter
(DEFUN |mjl-Counter+| ()
  (LET ((OBJ (MAKE-ARRAY '(2))))
    (SETF (ELT OBJ 0) |mjl-Counter|)
    (SETF (ELT OBJ 1) 0)
    OBJ))

;; Main routine
(FORMAT *MJ-STDOUT*
        "~A~%"
        (LET* ((OBJ
                (LET* ((OBJ (|mjl-Counter+|)) (VTABLE (ELT OBJ 0)))
                  (FUNCALL (GETHASH '|Init| VTABLE) OBJ 1)))
               (VTABLE (ELT OBJ 0)))
          (FUNCALL (GETHASH '|Next| VTABLE) OBJ)))