Advertisement
Guest User

Untitled

a guest
Mar 2nd, 2015
259
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 5.39 KB | None | 0 0
  1. ;  JAMES YU
  2. ;     +
  3. ; FRANK LIU
  4. ;
  5. ;      :)
  6.  
  7. #lang racket
  8.  
  9. (struct psymbol (type val) #:mutable)
  10.  
  11. (define (primp-assemble prog)
  12.   ; LINE COUNTER
  13.   (define lc 0)
  14.   ; BINDINGS
  15.   (define heap (make-hash))
  16.   (define (add-to-heap k v)
  17.     (cond [(hash-has-key? heap k) (error "duplicate")]
  18.           [else (hash-set! heap k v)]))
  19.   (define (lookup key)
  20.     (hash-ref heap key (lambda () (error "undefined"))))
  21.   ; FIRST PASS, GET VARIABLE NAMES
  22.   (define (get-vars p)
  23.     (if (empty? p)
  24.         empty
  25.         (match (first p)
  26.           ; HALT
  27.           [`(halt) (set! lc (add1 lc))
  28.                    (cons 0 (get-vars (rest p)))]
  29.           ; CONST
  30.           [`(const ,psym ,val) (add-to-heap psym (psymbol `imm val))
  31.                                (get-vars (rest p))]
  32.           ; DATA
  33.           [`(data ,psym (,n ,val)) (add-to-heap psym (psymbol `ind lc))
  34.                                    (set! lc (+ n lc))
  35.                                    (append (for/list ([i n])
  36.                                              `(lit ,val))
  37.                                            (get-vars (rest p)))]
  38.           [`(data ,psym ,val ...) (add-to-heap psym (psymbol `ind lc))
  39.                                   (append (for/list ([i val])
  40.                                             (set! lc (add1 lc))
  41.                                             `(lit ,i))
  42.                                           (get-vars (rest p)))]
  43.           ; LABEL
  44.           [`(label ,psym) (add-to-heap psym (psymbol `tgt lc))
  45.                           (get-vars (rest p))]
  46.           ; REGULAR PRIMP
  47.           [x (set! lc (add1 lc))
  48.              (cons x (get-vars (rest p)))])))
  49.  
  50.   ; EXECUTE PASS 1
  51.   (set! prog (get-vars prog))
  52.   ; RESOLVE NAMES
  53.   (define (resolve k v key n)
  54.     (cond [(and (symbol? (psymbol-val v))
  55.                 (symbol=? key (psymbol-val v)))
  56.            (if (and (symbol? n) (symbol=? n k))
  57.                (error "circular")
  58.                (set-psymbol-val! v n))]
  59.           [else (void)]))
  60.   (for ([(key value) heap])
  61.     (cond [(symbol? (psymbol-val value))
  62.            (define n (psymbol-val (lookup (psymbol-val value))))
  63.            (set-psymbol-val! value n)
  64.            (if (and (symbol? n)
  65.                     (symbol=? key n))
  66.                (error "circular")
  67.                (for ([(k v) heap])
  68.                  (resolve k v key n)))
  69.            ]
  70.           [else (void)]))
  71.   ; TEST PRINT
  72.   ;(for ([(key value) heap])
  73.   ;  (printf "~a:(~a,~a)\n" key (psymbol-type value) (psymbol-val value)))
  74.  
  75.   ; TYPE CHECKERS
  76.   (define (get-lit lit)
  77.     (cond [(number? lit) lit]
  78.           [(boolean? lit) lit]
  79.           [else (psymbol-val (lookup lit))]))
  80.   (define (get-tgt tgt)
  81.     (cond [(number? tgt) tgt]
  82.           [(symbol? tgt) (define l (lookup tgt))
  83.                          (if (symbol=? (psymbol-type l) `tgt)
  84.                              (psymbol-val l)
  85.                              `(,(psymbol-val l)))]
  86.           [else (get-opd tgt)]
  87.           ))
  88.   (define (get-imm imm)
  89.     (cond [(number? imm) imm]
  90.           [(boolean? imm) imm]
  91.           [else (define l (lookup imm))
  92.                 (if (symbol=? (psymbol-type l) `tgt)
  93.                     (error "incorrect")
  94.                     (psymbol-val l))]))
  95.   (define (get-ind ind)
  96.     (match ind
  97.       [`(,x) (if (number? x)
  98.                  ind
  99.                  (error "incorrect"))]
  100.       [x (define l (lookup ind))
  101.          (if (symbol=? (psymbol-type l) `ind)
  102.              `(,(psymbol-val l))
  103.              (error "incorrect")
  104.              )]))
  105.   (define (get-opd opd)
  106.     (match opd
  107.       [(? number? x) x]
  108.       [(? boolean? x) x]
  109.       [`(,imm) (if (number? imm)
  110.                  opd
  111.                  (error "incorrect"))]
  112.       [`(,imm ,ind) `(,(get-imm imm) ,(get-ind ind))]
  113.       [x (cond [(number? x) x]
  114.                [(boolean? x) x]
  115.                [else (define l (lookup x))
  116.                      (cond [(symbol=? (psymbol-type l) `imm) (psymbol-val l)]
  117.                            [(symbol=? (psymbol-type l) `ind) `(,(psymbol-val l))]
  118.                            [else (error "incorrect")])])]))
  119.   (define (get-dest dest)
  120.     (cond [(list? dest) (get-opd dest)]
  121.           [else (define l (lookup dest))
  122.                 (if (or (symbol=? (psymbol-type l) `imm)
  123.                         (symbol=? (psymbol-type l) `tgt))
  124.                     (error "incorrect")
  125.                     `(,(psymbol-val l)))]))
  126.   ; SUBSTITUTION
  127.   (define (subst p)
  128.     (cond [(empty? p) empty]
  129.           [else (match (first p)
  130.                   [`(lit ,sym) (cons (get-lit sym)
  131.                                      (subst (rest p)))]
  132.                   [`(jump ,tgt) (cons `(jump ,(get-tgt tgt))
  133.                                       (subst (rest p)))]
  134.                   [`(print-val ,opd) (cons `(print-val ,(get-opd opd))
  135.                                            (subst (rest p)))]
  136.                   [`(branch ,opd ,tgt) (cons `(branch ,(get-opd opd) ,(get-tgt tgt))
  137.                                              (subst (rest p)))]
  138.                   [`(,bin ,dest ,opd) (cons `(,bin ,(get-dest dest) ,(get-opd opd))
  139.                                             (subst (rest p)))]
  140.                   [`(,tern ,dest ,opd1 ,opd2) (cons `(,tern ,(get-dest dest) ,(get-opd opd1) ,(get-opd opd2))
  141.                                             (subst (rest p)))]
  142.                   [x (cons x (subst (rest p)))])]))
  143.   (set! prog (subst prog))
  144.   prog)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement