; Problem Set 10 Answers (include-book "irun") (in-package "M5") ; Below is a defconst template for a class named "Cons" with two fields "car" ; and "cdr". Fill in the blanks so that you define a "main" method that builds ; a ``ring of nats'' of size n, for any given integer n > 0. A ``ring of ; nats'' of size n is a "Cons" Object whose "cdr" fields contain other such ; Objects and whose "car" fields are the successive naturals (counting down) n, ; n-1, ..., 1. The "cdr" field of the Object with "car" 1 contains the Object ; with "car" n. For example, a ring of nats of size 3 might be drawn ; (3 . (2 . (1 . *))) ; ^ | ; |______________| ; Hint: I wouldn't attempt to do this by writing primitive bytecode for "main". ; I'd break the problem into several steps, implement methods for the steps, ; and use those methods in "main". (defconst *ps-10-ct* (make-ct (list (make class :name "Cons" :supers '("Object") :fields '("car" "cdr") :methods (list (make method :name "main" :formals '(n) :sync nil :code '((load 0) (invokestatic ("Cons" "cycle" 1)) (halt)) :xtbl nil) (make method :name "cons" :formals '(x y) :sync nil ; Build and initialize a new Cons object :code '((new "Cons") (dup) (dup) (load 0) (putfield ("Cons" "car")) (load 1) (putfield ("Cons" "cdr")) (xreturn)) :xtbl nil) (make method :name "natlist" :formals '(n) :sync nil ; Build a linked Cosn chain of nats starting at n. :code '((load 0) (ifeq 8) (load 0) (load 0) (const -1) (add) (invokestatic ("Cons" "natlist" 1)) (invokestatic ("Cons" "cons" 2)) (xreturn) (const -1) (xreturn)) :xtbl nil) (make method :name "smashlast" :formals '(x y) :sync nil ; Smash last Cons in x so cdr is y; ; x must be a linked list of Cons Objects terminating in some non-Cons. :code '((load 0) (getfield ("Cons" "cdr")) (instanceof "Cons") (ifeq 6) (load 0) (getfield ("Cons" "cdr")) (load 1) (invokestatic ("Cons" "smashlast" 2)) (return) (load 0) (load 1) (putfield ("Cons" "cdr")) (return)) :xtbl nil) (make method :name "cycle" :formals '(n) :sync nil ; Build a cyclic linked list with period n, by building a natlist ; of len n and smashing last to first. :code '((load 0) (invokestatic ("Cons" "natlist" 1)) (dup) (dup) (invokestatic ("Cons" "smashlast" 2)) (xreturn)) :xtbl nil) ))))) ; Here is a call of irun to test your state for a ring of size 5. The results ; of running my code are shown in the comment below. My code requires 141 ; steps, but your code can take how ever many steps it needs. (irun (make state :tt (list (make thread :id 0 :cs (push (make frame :pc 0 :locs '(5) :stk nil :mloc '("Cons" "main" 0)) nil) :stat 'active :ref nil)) :hp nil :ct *ps-10-ct*)) #| Welcome to irun. Type :help for help. ----------------------------------------------------------------- Scene 0 Current thread = (cid 0) = 0 Current state = (s 0) = (MODIFY 0 (S PROTO) :PC 0 :LOCS '(5) :STK NIL :NEXT-INST '(LOAD 0) :MLOC '("Cons" "main" 0)) cmd: :stepn 141 ----------------------------------------------------------------- Scene 1 Current thread = (cid 1) = 0 Current state = (s 1) = (MODIFY 0 (S 0) :PC 2 :STK '((REF 4)) :NEXT-INST '(HALT) :HP '(((REF 0) (("Cons" (("car" 1) ("cdr" (REF 4)))) ("Object" (("monitor" 0) ("mcount" 0) ("wait-set" 0))))) ((REF 1) (("Cons" (("car" 2) ("cdr" (REF 0)))) ("Object" (("monitor" 0) ("mcount" 0) ("wait-set" 0))))) ((REF 2) (("Cons" (("car" 3) ("cdr" (REF 1)))) ("Object" (("monitor" 0) ("mcount" 0) ("wait-set" 0))))) ((REF 3) (("Cons" (("car" 4) ("cdr" (REF 2)))) ("Object" (("monitor" 0) ("mcount" 0) ("wait-set" 0))))) ((REF 4) (("Cons" (("car" 5) ("cdr" (REF 3)))) ("Object" (("monitor" 0) ("mcount" 0) ("wait-set" 0))))))) |#