|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T r
Length: 6653 (0x19fd)
Types: TextFile
Names: »regsim.scm«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/gnu-31mar87/scheme/psets/regsim.scm«
;;; This is the register machine simulator
;;; file ps9-regsim.scm
;;; Magic syntax hack... DO NOT expect to understand this. Hal doesn't,
;;; and he wrote it!
(enable-language-features)
(define (cons* first-element . rest-elements)
(let loop ((this-element first-element)
(rest-elements rest-elements))
(if (null? rest-elements)
this-element
(cons this-element
(loop (car rest-elements)
(cdr rest-elements))))))
(define-macro (define-machine name . body)
`(DEFINE ,name
(CHECK-SYNTAX-AND-ASSEMBLE '(DEFINE-MACHINE ,name . ,body))))
(add-syntax! 'define-machine
(macro (name . body)
`(DEFINE ,name
(CHECK-SYNTAX-AND-ASSEMBLE '(DEFINE-MACHINE ,name . ,body)))))
(disable-language-features)
;;; To set up a simulation:
(define (check-syntax-and-assemble machine-description)
(define (check-for symbol structure)
(cond ((not (pair? structure))
(error "bad machine description format" structure))
((not (eq? (car structure) symbol))
(error "bad machine description keyword"
(list symbol structure)))
(else 'ok)))
(check-for 'define-machine machine-description)
(check-for 'registers (nth 2 machine-description))
(check-for 'operations (nth 3 machine-description))
(check-for 'controller (nth 4 machine-description))
(assemble (cdr (nth 2 machine-description))
(cdr (nth 3 machine-description))
(cdr (nth 4 machine-description))))
(define (assemble registers operations controller)
(let ((machine (make-new-machine)))
(set-up-registers machine registers)
(set-up-operations machine operations)
(set-up-controller machine controller)
machine))
(define (set-up-registers machine registers)
(remote-set! machine '*registers* registers)
(mapc (lambda (register-name)
(remote-define machine register-name
(make-register register-name)))
registers))
(define (make-register name)
(cons nil name))
(define fetch car)
(define (set-up-operations machine operations)
(remote-set! machine '*instruction-map*
(mapcar (lambda (operation)
(cons operation
(make-machine-instruction machine
operation)))
operations)))
(define (set-up-controller machine controller)
(define (build-instruction-list op-list)
(if (null? op-list)
'()
(let ((rest-of-instructions
(build-instruction-list (cdr op-list))))
(if (symbol? (car op-list)) ; An atomic symbol
; indicates a label
(sequence (declare-label! machine
(car op-list)
rest-of-instructions)
rest-of-instructions)
(cons (lookup-operation machine (car op-list))
rest-of-instructions)))))
(remote-set! machine
'*start*
(build-instruction-list controller)))
(define (declare-label! machine label labeled-entry)
(let ((defined-labels (remote-get machine '*labels*)))
(if (memq label defined-labels)
(error "Multiply defined label" label)
(sequence
(remote-define machine label labeled-entry)
(remote-set! machine
'*labels*
(cons label defined-labels))))))
(define (lookup-operation machine op)
(let ((pair (assoc op
(remote-get machine
'*instruction-map*))))
(if (null? pair)
(error "Undeclared op" op)
(cdr pair))))
(define (remote-get machine variable)
(eval variable machine))
(define (remote-set! machine variable value)
(eval (list 'set! variable (list 'quote value))
machine))
(define (remote-define machine variable value)
(eval (list 'define variable (list 'quote value))
machine))
(define (make-machine-instruction machine op)
(eval (list 'lambda '() op) machine))
(define (remote-fetch machine register-name)
(car (remote-get machine register-name)))
(define (remote-assign machine register-name value)
(set-car! (remote-get machine register-name) value))
(define (start machine)
(eval '(sequence (goto *start*)
(execute-next-instruction))
machine))
;;monitored stack
(define (make-stack)
(define s nil)
(define number-pushes 0)
(define max-depth 0)
(define (push x)
(set! s (cons x s))
(set! number-pushes (1+ number-pushes))
(set! max-depth (max (length s) max-depth)))
(define (pop)
(let ((top (car s)))
(set! s (cdr s))
top))
(define (initialize)
(set! s nil)
(set! number-pushes 0)
(set! max-depth 0))
(define (print-statistics)
(print (list 'total-pushes: number-pushes
'maximum-depth: max-depth)))
(define (dispatch message)
(cond ((eq? message 'push) push)
((eq? message 'pop) (pop))
((eq? message 'initialize) (initialize))
((eq? message 'print-statistics) (print-statistics))
(else (error "Unknown request -- STACK"
message))))
dispatch)
(define (make-new-machine)
(make-environment
;;routine to assign values to registers
(define (assign register value)
(set-car! register value)
(normal-next-instruction))
;;saving and restoring registers
(define the-stack (make-stack))
(define (initialize-stack)
(the-stack 'print-statistics)
(the-stack 'initialize))
(define (save reg)
((the-stack 'push) (fetch reg))
(normal-next-instruction))
(define (restore reg)
(assign reg (the-stack 'pop)))
;;sequencing instructions
(define program-counter (make-register 'program-counter))
(define (execute-next-instruction)
(cond ((null? (fetch program-counter)) 'done)
(else
((car (fetch program-counter)))
(execute-next-instruction))))
(define (normal-next-instruction)
(set-car! program-counter (cdr (fetch program-counter))))
(define (goto new-sequence)
(set-car! program-counter new-sequence))
(define (branch predicate alternate-next)
(if predicate
(goto alternate-next)
(normal-next-instruction)))
;; routine for simulating special instructions
(define (perform op)
(normal-next-instruction))
;; special variables used by the assembler
(define *instruction-map* nil)
(define *labels* nil)
(define *registers* nil)
(define *start* nil)
))