[<<][staapl][>>][..]
Fri Apr 11 15:03:07 EDT 2008

broken functional compiler

paste it here, so i can get the imperative back online:


;; To the macro layer, code and labels are distinct entities
;; represented by abstract target-word data type and reversed assembly
;; code lists respectively. After compilation, the code lists are
;; permanently attached to the word structs. During compilation, no
;; side effects are made, so continuations can be used for
;; optimizations.



(define (compile-word input-word)

  ;; Label generation is stateful, but that's ok since we don't care
  ;; much about the counter values. They are just for readability.
  (define next (make-counter 0))
  (define (label (name (format "_L~a" (next))))
    (make-simple-target-word
     (string->symbol
      (format "~a" name))))

  ;; Get the macro code, and create a start thunk and set up the
  ;; grabber parameter.
  (define macro (target-word-code input-word))
  (define name  (target-word-name input-word))
  (define grab-words (make-parameter #f))
  (define (go)
    ((grab-words)
     (macro->code macro name)))

  ;; Split needs to be purely functional so continuations can be used
  ;; freely when compiling code, discarding the split word state if
  ;; necessary.
  (define word/code
    (let ((tag (make-continuation-prompt-tag 'compile-word)))
      (set-target-word-code! input-word #f)
      (parameterize-words-ns!
       (macro) ((semicolon (ns (scat) postpone-exit)))
       (parameterize
           ((target-make-label label)
            (target-split #f)) ;; Ensure side-effects are local.

         ;; State updates directed by calls to 'split'.
         (let update ((words '())               ;; listof (word . code)
                      (current-word input-word)
                      (continue go))            ;; continuation thunk

           ;; Split needs to be purely functional so continuations can be used
           ;; freely when compiling code.
           (target-split
            (lambda (state new-word)
              (let ((code  (state-data state))
                    (stack (state-stack state)))
                (shift-at
                 tag
                 chunk
                 (update (cons ;; no assignments!
                          (list current-word chunk)
                          words)
                         new-word
                         (lambda () (k (make-state stack '())))))
                 tag))))

           ;; After 'macro->code' we end up here to record the last bit
           ;; of code, collect everything and exit from 'go' and thus
           ;; the 'update' loop.
           (grab-words
            (lambda (final-code)
              (cons (list current-word final-code) words)))

           ;; Continue computation
           (reset-at tag (continue)))))))






  ;; Link up structures, and return a list of words.
  (map* (lambda (word code)
          (set-target-word-code! word code)
          word)
        word/code))




[Reply][About]
[<<][staapl][>>][..]