allocate-registers jump, compare, environment allocate-registers zero, one, two, nil allocate-registers free allocate-registers lst, end, cell, element, target, c allocate-registers target1, target2 ;; Initialize constant registers li zero, 0 ; zero is useful for copying one register's contents to another li one, 1 ; one is useful for allocating a memory location li two, 2 ; two is useful for allocating two consecutive memory locations li nil, -1 ; nil represents an empty list ;; Initialize the free register to point to the beginning of memory li free, 0 ; free points to the next available memory location ;; Read a list into memory: lst points to the start; end points to the end ; Allocate a memory location for a pointer to the start of the list add lst, free, zero add free, free, one ; The just-allocate memory location is the initial end of the list add end, lst, zero read-element: ; Read a number to find out if there is another element in the list ; (0 means there is no more element in the list) read element li jump, read-end jeqz element, jump ; Read the next element in the list read element ; Allocate two consecutive memory locations for the new element and for ; a pointer to the rest of the list add cell, free, zero add free, free, two st element, cell st cell, end add end, cell, one ; Loop li jump, read-element j jump read-end: ; Terminate the list: the rest of the list is the empty list st nil, end ld lst, lst ; Find out from the user what we are looking for read target1 read target2 two-members: ; Construct (lambda (lst) (member? target2 lst)) and put it into c add c, free, zero add free, free, two li jump, anonymous-function-2 st jump, c add environment, c, one st target2, environment ; Invoke find-c, with our target1 as their target add target, target1, zero li jump, find-c j jump anonymous-function-2: add environment, c, one ld target, environment ; fall through member: ; Construct (lambda (lst) (if (null? lst) #f #t)) and put it into c add c, free, zero add free, free, one li jump, anonymous-function-1 st jump, c ; Invoke find-c, with our target as their target li jump, find-c j jump anonymous-function-1: sne compare, lst, nil write compare halt find-c: ; If the list is empty ... seq compare, lst, nil li jump, find-c-1 jeqz compare, jump ; ... invoke the procedure represented by c ld jump, c j jump find-c-1: ; If the first element in the list is the target ... ld element, lst seq compare, element, target li jump, find-c-2 jeqz compare, jump ; ... invoke the procedure represented by c ld jump, c j jump find-c-2: ; Advance lst to the rest of the list add lst, lst, one ld lst, lst ; Continue with the rest of the list li jump, find-c j jump test empty-list >>> 0 >>> 10 ; target1 >>> 20 ; target2 0 test singleton-list-not-found >>> 1 >>> 3 >>> 0 >>> 10 ; target1 >>> 20 ; target2 0 test singleton-list-found >>> 1 >>> 3 >>> 0 >>> 3 ; target1 >>> 20 ; target2 0 test duple-not-found >>> 1 >>> 3 >>> 1 >>> 20 >>> 0 >>> 10 ; target1 >>> 20 ; target2 0 test duple-half-found >>> 1 >>> 3 >>> 1 >>> 10 >>> 0 >>> 3 ; target1 >>> 20 ; target2 0 test duple-found >>> 1 >>> 3 >>> 1 >>> 10 >>> 0 >>> 3 ; target1 >>> 10 ; target2 1 test non-empty-list-not-found >>> 1 >>> 3 >>> 100 >>> 10 >>> -1 >>> -2 >>> 0 >>> -10 ; target1 >>> -2 ; target2 0 test non-empty-list-half-found >>> 1 >>> 3 >>> 100 >>> 10 >>> -1 >>> -2 >>> 0 >>> 10 ; target1 >>> 2 ; target2 0 test non-empty-list-found >>> 1 >>> 3 >>> 100 >>> 10 >>> -1 >>> -2 >>> 0 >>> 10 ; target1 >>> -2 ; target2 1