Tôi mới dùng vợt/sơ đồ, vì vậy tôi quyết định tìm hiểu bằng cách triển khai bộ mô phỏng cho DCPU-16, một bộ xử lý 16 bit đơn giản.Thành phần Racket/Scheme thích hợp cho mã này là gì?
Câu hỏi của tôi là: Cách tốt hơn để triển khai giải pháp của tôi là gì?
Đây là giải pháp tôi đã tấn công cùng nhau để kiểm soát sổ đăng ký của cpu. Điểm chính là cho phép các chức năng thay đổi sổ đăng ký để được xích lại với nhau. Ví dụ:
; Increment value stored in register r-id
; returns the updated register
;
; Reg - the register structure
; (reg-inc Reg 'SP)
(define (reg-inc reg r-id)
(reg-write reg r-id (+ (reg-read reg r-id) 1)))
; chain them together
;(reg-inc (reg-inc Reg 'SP)
; 'PC)
;
; returns structure with both 'SP and 'PC incremented
Toàn bộ văn bản của giải pháp đăng ký của tôi bên dưới. My full program cũng có trên github. Có rất nhiều lặp lại logic, tôi biết có phải là một cách dễ dàng hơn:
(struct registers (A B C X Y Z I J SP PC O Pa Pb Paadr Pbadr CLK)
#:transparent)
(define Reg (registers 0 0 0 0 0 0 0 0 #x10000 0 0 0 0 0 0 0))
(define (reg-name n)
(case n
[(0) 'A]
[(1) 'B]
[(2) 'C]
[(3) 'X]
[(4) 'Y]
[(5) 'Z]
[(6) 'I]
[(7) 'J]
[(8) 'SP]
[(9) 'PC]
[(10) 'O]
[(11) 'Pa]
[(12) 'Pb]
[(13) 'Paadr]
[(14) 'Pbadr]
[(15) 'CLK]
[else (error "Invalid register")]))
(define (reg-id s)
(cond
[(eq? 'A s) 0]
[(eq? 'B s) 1]
[(eq? 'C s) 2]
[(eq? 'X s) 3]
[(eq? 'Y s) 4]
[(eq? 'Z s) 5]
[(eq? 'I s) 6]
[(eq? 'J s) 7]
[(eq? 'SP s) 8]
[(eq? 'PC s) 9]
[(eq? 'O s) 10]
[(eq? 'Pa s) 11]
[(eq? 'Pb s) 12]
[(eq? 'Paadr s) 13]
[(eq? 'Pbadr s) 14]
[(eq? 'CLK s) 15]))
(define (reg-read reg r)
(if (symbol? r)
(reg-read reg (reg-id r))
(case r
[(0) (registers-A reg)]
[(1) (registers-B reg)]
[(2) (registers-C reg)]
[(3) (registers-X reg)]
[(4) (registers-Y reg)]
[(5) (registers-Z reg)]
[(6) (registers-I reg)]
[(7) (registers-J reg)]
[(8) (registers-SP reg)]
[(9) (registers-PC reg)]
[(10) (registers-O reg)]
[(11) (registers-Pa reg)]
[(12) (registers-Pb reg)]
[(13) (registers-Paadr reg)]
[(14) (registers-Pbadr reg)]
[(15) (registers-CLK reg)]
[else (error "Invalid register")])))
(define (reg-write reg r val)
(if (symbol? r)
(reg-write reg (reg-id r) val)
(let ([mask-val (bitwise-and val #xffff)])
(case r
[(0) (struct-copy registers reg [A mask-val])]
[(1) (struct-copy registers reg [B mask-val])]
[(2) (struct-copy registers reg [C mask-val])]
[(3) (struct-copy registers reg [X mask-val])]
[(4) (struct-copy registers reg [Y mask-val])]
[(5) (struct-copy registers reg [Z mask-val])]
[(6) (struct-copy registers reg [I mask-val])]
[(7) (struct-copy registers reg [J mask-val])]
[(8) (struct-copy registers reg [SP mask-val])]
[(9) (struct-copy registers reg [PC mask-val])]
[(10) (struct-copy registers reg [O mask-val])]
[(11) (struct-copy registers reg [Pa mask-val])]
[(12) (struct-copy registers reg [Pb mask-val])]
[(13) (struct-copy registers reg [Paadr mask-val])]
[(14) (struct-copy registers reg [Pbadr mask-val])]
[(15) (struct-copy registers reg [CLK mask-val])]
[else (error "Invalid register")]))))
Cập nhật:
Nhờ sugestions oobviat của tôi đã refactored sử dụng danh sách. Phần khó khăn duy nhất là cập nhật một giá trị trong danh sách. Tôi đã viết một thủ tục cho bản đồ đó sẽ cập nhật thanh ghi mong muốn và để lại những người khác với giá trị ban đầu của họ:
;; a-list of registers and initial values
(define (build-reg)
'((A . 0) (B . 0) (C . 0) (X . 0)
(Y . 0) (Z . 0) (I . 0) (J . 0)
(SP . 0) (PC . 0) (O . 0) (Pa . 0)
(Pb . 0) (Paadr . 0) (Pbadr . 0) (CLK . 0)))
(define *REF-REG* (build-reg)) ; used to determine structure
(define (reg-name n)
(if (symbol? n)
n
(car (list-ref *REF-REG* n))))
(define (reg-id s)
(- (length *REF-REG*)
(length (memf (lambda (arg)
(eq? s (car arg)))
*REF-REG*))))
(define (reg-write reg r val)
(let ([r-name (reg-name r)])
(define (reg-write-helper entry)
(if (eq? r-name
(car entry))
(cons r-name val)
entry))
(map reg-write-helper reg)))
(define (reg-read reg r)
(cdr (assoc (reg-name r) reg)))
Cấu trúc không có thủ tục nội tâm không? Tôi chắc chắn nó. – leppie
@leppie, cấu trúc không có tên của chúng trong thông tin nội tâm. –